From a329cd940c75734bf1772d7418390ae6c378d647 Mon Sep 17 00:00:00 2001 From: Hari Dahal Date: Thu, 25 Jan 2018 12:49:10 -0500 Subject: [PATCH 1/4] release 0 - shorten given url and redirect --- source/app/controllers/urls_controller.rb | 36 +++++++++++++++++++ source/app/models/url.rb | 10 ++++++ source/app/views/urls/index.html.erb | 10 ++++++ source/app/views/urls/new.html.erb | 26 ++++++++++++++ source/config/routes.rb | 3 ++ .../db/migrate/20180125135057_create_urls.rb | 13 +++++++ source/db/schema.rb | 24 +++++++++++++ source/spec/models/url_spec.rb | 5 +++ 8 files changed, 127 insertions(+) create mode 100644 source/app/models/url.rb create mode 100644 source/app/views/urls/index.html.erb create mode 100644 source/app/views/urls/new.html.erb create mode 100644 source/db/migrate/20180125135057_create_urls.rb create mode 100644 source/db/schema.rb create mode 100644 source/spec/models/url_spec.rb diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index ef26710..836c857 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,38 @@ class UrlsController < ApplicationController + def create + @url = Url.new(urls_params) + + if @url.save + redirect_to urls_path + else + render 'new' + end + end + + def index + @urls = Url.all + end + + def new + @url = Url.new + end + + def route_me + url = Url.find_by_short_url params[:short_url] + + if url.nil? + redirect_to root_path + else + redirect_to url.long_url + end + + + end + + private + + def urls_params + params.require(:url).permit(:long_url) + end + end diff --git a/source/app/models/url.rb b/source/app/models/url.rb new file mode 100644 index 0000000..8958f84 --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,10 @@ +class Url < ActiveRecord::Base + before_save :shorten_url + validates :long_url, presence: true + + private + + def shorten_url + self.short_url = (0...7).map { [*'0'..'9', *'A'..'Z', *'a'..'z'].sample }.join + end +end diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb new file mode 100644 index 0000000..49874b5 --- /dev/null +++ b/source/app/views/urls/index.html.erb @@ -0,0 +1,10 @@ +

Welcome to URL Shortner | Home

+<%= link_to 'Shorten a URL', new_url_path %> + +

+ +
    + <% @urls.each do |url| %> +
  1. <%= url.long_url %> | <%= url.short_url %>
  2. + <% end %> +
diff --git a/source/app/views/urls/new.html.erb b/source/app/views/urls/new.html.erb new file mode 100644 index 0000000..8d251ee --- /dev/null +++ b/source/app/views/urls/new.html.erb @@ -0,0 +1,26 @@ +<%= form_for :url, url: urls_path, local: true do |form| %> + + <% if @url.errors.any? %> +
+

+ <%= pluralize(@url.errors.count, "error") %> couldn't save this url +

+ +
+ <% end %> + + + +

+ <%= form.label 'Enter URL: ' %> <%= form.text_field :long_url %> +

+ + +

<%= form.submit %>

+<% end %> + +<%= link_to 'Back', urls_path %> \ No newline at end of file diff --git a/source/config/routes.rb b/source/config/routes.rb index 3f66539..ff24be8 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -53,4 +53,7 @@ # # (app/controllers/admin/products_controller.rb) # resources :products # end + resources :urls + get '/:short_url' => 'urls#route_me' + root 'urls#index' end diff --git a/source/db/migrate/20180125135057_create_urls.rb b/source/db/migrate/20180125135057_create_urls.rb new file mode 100644 index 0000000..2ce4b82 --- /dev/null +++ b/source/db/migrate/20180125135057_create_urls.rb @@ -0,0 +1,13 @@ +class CreateUrls < ActiveRecord::Migration + def change + create_table :urls do |t| + t.text :long_url + t.text :short_url + t.integer :visit_count + t.datetime :created_at + t.datetime :updated_at + + t.timestamps + end + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb new file mode 100644 index 0000000..37a0462 --- /dev/null +++ b/source/db/schema.rb @@ -0,0 +1,24 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20180125135057) do + + create_table "urls", force: true do |t| + t.text "long_url" + t.text "short_url" + t.integer "visit_count" + t.datetime "created_at" + t.datetime "updated_at" + end + +end diff --git a/source/spec/models/url_spec.rb b/source/spec/models/url_spec.rb new file mode 100644 index 0000000..209ca4c --- /dev/null +++ b/source/spec/models/url_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Url, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From a5a2db0f2f133a2f90b19c79b545f40ab392d55a Mon Sep 17 00:00:00 2001 From: Hari Dahal Date: Thu, 25 Jan 2018 13:30:14 -0500 Subject: [PATCH 2/4] release 1 - count clicks --- source/app/controllers/urls_controller.rb | 1 + source/app/models/url.rb | 4 +++- source/app/views/urls/index.html.erb | 2 +- .../db/migrate/20180125182043_set_url_visit_count_default.rb | 5 +++++ .../20180125182544_rename_visit_count_to_click_count.rb | 5 +++++ source/db/schema.rb | 4 ++-- 6 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 source/db/migrate/20180125182043_set_url_visit_count_default.rb create mode 100644 source/db/migrate/20180125182544_rename_visit_count_to_click_count.rb diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 836c857..a28a5a0 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -23,6 +23,7 @@ def route_me if url.nil? redirect_to root_path else + url.update('click_count' => url.click_count + 1) redirect_to url.long_url end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 8958f84..6339260 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -5,6 +5,8 @@ class Url < ActiveRecord::Base private def shorten_url - self.short_url = (0...7).map { [*'0'..'9', *'A'..'Z', *'a'..'z'].sample }.join + if short_url.nil? + self.short_url = (0...7).map { [*'0'..'9', *'A'..'Z', *'a'..'z'].sample }.join + end end end diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index 49874b5..c3d697a 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -5,6 +5,6 @@
    <% @urls.each do |url| %> -
  1. <%= url.long_url %> | <%= url.short_url %>
  2. +
  3. <%= url.long_url %> | <%= url.short_url %> | <%= url.click_count %>
  4. <% end %>
diff --git a/source/db/migrate/20180125182043_set_url_visit_count_default.rb b/source/db/migrate/20180125182043_set_url_visit_count_default.rb new file mode 100644 index 0000000..e14b60a --- /dev/null +++ b/source/db/migrate/20180125182043_set_url_visit_count_default.rb @@ -0,0 +1,5 @@ +class SetUrlVisitCountDefault < ActiveRecord::Migration + def change + change_column :urls, :visit_count, :integer, default: 0 + end +end diff --git a/source/db/migrate/20180125182544_rename_visit_count_to_click_count.rb b/source/db/migrate/20180125182544_rename_visit_count_to_click_count.rb new file mode 100644 index 0000000..b6a25b2 --- /dev/null +++ b/source/db/migrate/20180125182544_rename_visit_count_to_click_count.rb @@ -0,0 +1,5 @@ +class RenameVisitCountToClickCount < ActiveRecord::Migration + def change + rename_column :urls, :visit_count, :click_count + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index 37a0462..4190ac5 100644 --- a/source/db/schema.rb +++ b/source/db/schema.rb @@ -11,12 +11,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180125135057) do +ActiveRecord::Schema.define(version: 20180125182544) do create_table "urls", force: true do |t| t.text "long_url" t.text "short_url" - t.integer "visit_count" + t.integer "click_count", default: 0 t.datetime "created_at" t.datetime "updated_at" end From 6b4ecd90d494b28c28c9101548105fcd79876faf Mon Sep 17 00:00:00 2001 From: Hari Dahal Date: Fri, 26 Jan 2018 10:14:04 -0500 Subject: [PATCH 3/4] release 2&3 - added url validations --- source/app/models/url.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 6339260..b1b2399 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,6 +1,10 @@ +require 'uri' +require 'net/http' + class Url < ActiveRecord::Base before_save :shorten_url validates :long_url, presence: true + validate :long_url_proper_format, :long_url_responds private @@ -9,4 +13,22 @@ def shorten_url self.short_url = (0...7).map { [*'0'..'9', *'A'..'Z', *'a'..'z'].sample }.join end end + + def long_url_proper_format + unless long_url.start_with? 'http://', 'https://' + errors.add(:long_url, 'not in a valid format. (must start with http:// or https://)') + end + end + + def long_url_responds + link = URI.parse(long_url) + if link.is_a?(URI::HTTP) || link.is_a?(URI::HTTPS) + Net::HTTP.get_response(link) + else + errors.add(:long_url, 'must be reachable.') + end + rescue + errors.add(:long_url, 'must be reachable.') + end + end From d16c76c28dbaecf5d50b2fa71acc90a27ff99025 Mon Sep 17 00:00:00 2001 From: Hari Dahal Date: Fri, 26 Jan 2018 10:21:57 -0500 Subject: [PATCH 4/4] added bootstrap to FrontEnd layouts --- source/app/views/layouts/application.html.erb | 14 +++++++++++++- source/app/views/urls/index.html.erb | 3 ++- source/app/views/urls/new.html.erb | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index f946432..ebd783d 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -5,10 +5,22 @@ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> + + + + + + -<%= yield %> +
+ +
+ <%= yield %> +
diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index c3d697a..8433e95 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -1,8 +1,9 @@

Welcome to URL Shortner | Home

-<%= link_to 'Shorten a URL', new_url_path %> +<%= link_to 'Shorten a URL', new_url_path, class: "btn btn-primary" %>

+
    <% @urls.each do |url| %>
  1. <%= url.long_url %> | <%= url.short_url %> | <%= url.click_count %>
  2. diff --git a/source/app/views/urls/new.html.erb b/source/app/views/urls/new.html.erb index 8d251ee..a57d3c8 100644 --- a/source/app/views/urls/new.html.erb +++ b/source/app/views/urls/new.html.erb @@ -16,11 +16,11 @@

    - <%= form.label 'Enter URL: ' %> <%= form.text_field :long_url %> + <%= form.label 'Enter URL: ' %> <%= form.text_field :long_url, class: "form-control" %>

    -

    <%= form.submit %>

    +

    <%= form.submit class: "btn btn-primary"%>

    <% end %> <%= link_to 'Back', urls_path %> \ No newline at end of file