diff --git a/source/Gemfile b/source/Gemfile index 9627b8b..4d97f83 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' - +gem 'pry' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.1.6' # Use sqlite3 as the database for Active Record diff --git a/source/Gemfile.lock b/source/Gemfile.lock index fcf8b98..ab6209f 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -29,6 +29,7 @@ GEM tzinfo (~> 1.1) arel (5.0.1.20140414130214) builder (3.2.2) + coderay (1.1.2) coffee-rails (4.0.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) @@ -50,9 +51,13 @@ GEM json (1.8.1) mail (2.6.1) mime-types (>= 1.16, < 3) + method_source (0.9.0) mime-types (2.4.1) minitest (5.4.2) multi_json (1.10.1) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) rack (1.5.2) rack-test (0.6.2) rack (>= 1.0) @@ -128,6 +133,7 @@ DEPENDENCIES coffee-rails (~> 4.0.0) jbuilder (~> 2.0) jquery-rails + pry rails (= 4.1.6) rspec-rails sass-rails (~> 4.0.3) @@ -136,3 +142,6 @@ DEPENDENCIES sqlite3 turbolinks uglifier (>= 1.3.0) + +BUNDLED WITH + 1.16.1 diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index ef26710..e278eea 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,34 @@ class UrlsController < ApplicationController + + def short + @url = Url.find_by(:short_url => params[:id]) + @url.increment(:click_count) + redirect_to @url[:long_url] + end + + def index + @urls = Url.all + end + + def show + @url = Url.find(params[:id]) + end + + def new + @url = Url.new + end + + def create + @url = Url.new(url_params) + if @url.save + redirect_to url_path(@url) + else + render 'new' + end + end + + private + def url_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..4073874 --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,20 @@ +require 'net/http' + +class Url < ActiveRecord::Base + before_create :shorten_url + validates :long_url, presence: true, allow_blank: false + validate :validate_url + + def validate_url + uri = URI("#{self.long_url}") + # this doesn't work if the input isn't a url, i.e., it only works if an error code is returned + if res = Net::HTTP.get_response(uri) + else res.code = "x" + end + self.errors.add(:base, "This URL is invalid, #{res.message}") if res.code != "200" + end + + def shorten_url + self.short_url = "!#{(0..3).map{ rand(36).to_s(36) }.join}" + end +end \ No newline at end of file diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb new file mode 100644 index 0000000..80d7be2 --- /dev/null +++ b/source/app/views/urls/index.html.erb @@ -0,0 +1,5 @@ +

All the URLs

+ +<% @urls.each do |url| %> + <%= url.long_url %>
+<% end %> \ No newline at end of file diff --git a/source/app/views/urls/new.html.erb b/source/app/views/urls/new.html.erb new file mode 100644 index 0000000..5392021 --- /dev/null +++ b/source/app/views/urls/new.html.erb @@ -0,0 +1,11 @@ +<% if @url.errors.any? %> + <% @url.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +<% end %> + +<%= form_for @url do |f| %> + <%= f.label "Enter a URL" %> + <%= f.url_field :long_url, :required => true %> +<%= f.submit %> +<% end %> diff --git a/source/app/views/urls/show.html.erb b/source/app/views/urls/show.html.erb new file mode 100644 index 0000000..a9cbb77 --- /dev/null +++ b/source/app/views/urls/show.html.erb @@ -0,0 +1,2 @@ +The URL you entered: <%= @url.long_url %>
    +Its short version: <%= link_to "http://localhost:3000/urls/#{@url.short_url}", @url.short_url %> \ No newline at end of file diff --git a/source/config/application.rb b/source/config/application.rb index 9a1de00..9b24bf8 100644 --- a/source/config/application.rb +++ b/source/config/application.rb @@ -5,6 +5,7 @@ # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) +require 'pry' module Source class Application < Rails::Application diff --git a/source/config/routes.rb b/source/config/routes.rb index 3f66539..1d1092e 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,4 +1,10 @@ Rails.application.routes.draw do + + get 'urls/:id', to: 'urls#short', id: /[:!].{4}/ + + resources :urls + + # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". diff --git a/source/db/migrate/20180514183131_urls.rb b/source/db/migrate/20180514183131_urls.rb new file mode 100644 index 0000000..c27d759 --- /dev/null +++ b/source/db/migrate/20180514183131_urls.rb @@ -0,0 +1,8 @@ +class Urls < ActiveRecord::Migration + def change + create_table :urls do |t| + t.string :long_url + t.string :short_url + end + end +end diff --git a/source/db/migrate/20180515131738_add_click_count_to_urls.rb b/source/db/migrate/20180515131738_add_click_count_to_urls.rb new file mode 100644 index 0000000..93b0e1f --- /dev/null +++ b/source/db/migrate/20180515131738_add_click_count_to_urls.rb @@ -0,0 +1,5 @@ +class AddClickCountToUrls < ActiveRecord::Migration + def change + add_column :urls, :click_count, :integer, default: 0 + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb new file mode 100644 index 0000000..c236329 --- /dev/null +++ b/source/db/schema.rb @@ -0,0 +1,22 @@ +# 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: 20180515131738) do + + create_table "urls", force: true do |t| + t.string "long_url" + t.string "short_url" + t.integer "click_count", default: 0 + end + +end