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