diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index ef26710..a28a5a0 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,39 @@ 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 + url.update('click_count' => url.click_count + 1) + 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..b1b2399 --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,34 @@ +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 + + def shorten_url + if short_url.nil? + 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 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 new file mode 100644 index 0000000..8433e95 --- /dev/null +++ b/source/app/views/urls/index.html.erb @@ -0,0 +1,11 @@ +

Welcome to URL Shortner | Home

+<%= 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. + <% 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..a57d3c8 --- /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, class: "form-control" %> +

+ + +

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

+<% 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/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 new file mode 100644 index 0000000..4190ac5 --- /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: 20180125182544) do + + create_table "urls", force: true do |t| + t.text "long_url" + t.text "short_url" + t.integer "click_count", default: 0 + 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