From da9b8aef04106ce17c7f75c7dc854522104012e4 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Mon, 14 May 2018 18:05:28 -0400 Subject: [PATCH 01/15] Release 0: Simple Shortener. --- source/Gemfile | 2 +- source/Gemfile.lock | 9 +++ source/app/controllers/urls_controller.rb | 32 +++++++++++ source/app/models/url.rb | 12 ++++ source/app/views/urls/index.html.erb | 8 +++ source/app/views/urls/new.html.erb | 4 ++ source/config/routes.rb | 56 +------------------ .../db/migrate/20180514210613_create_urls.rb | 10 ++++ source/db/schema.rb | 23 ++++++++ source/spec/models/url_spec.rb | 5 ++ 10 files changed, 106 insertions(+), 55 deletions(-) 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/20180514210613_create_urls.rb create mode 100644 source/db/schema.rb create mode 100644 source/spec/models/url_spec.rb diff --git a/source/Gemfile b/source/Gemfile index 9627b8b..633a5c0 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -38,4 +38,4 @@ gem 'spring', group: :development # Use debugger # gem 'debugger', group: [:development, :test] gem 'rspec-rails', group: [:development, :test] - + gem 'pry', group: [:development, :test] 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..aa3aca2 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,34 @@ class UrlsController < ApplicationController + before_action :set_url, only: [:show] + + def index + @urls = Url.all + end + + def new + @url = Url.new + end + + def create + @url = Url.new(url_params) + if @url.save + redirect_to urls_path + else + redirect_to new_url_path(@url) + end + end + + def show + redirect_to "http://#{@url.long_url}" + end + + private + + def set_url + @url = Url.find_by(short_url: params[:short_url]) + end + + def url_params + params.require(:url).permit(:long_url, :short_url) + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb new file mode 100644 index 0000000..6224902 --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,12 @@ +class Url < ActiveRecord::Base + validates :short_url, uniqueness: true + before_save :create_short_url + + def create_short_url + begin + short_url = SecureRandom.hex(4) + end while Url.where(short_url: short_url).exists? + + self.short_url = short_url + 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..bcb1aca --- /dev/null +++ b/source/app/views/urls/index.html.erb @@ -0,0 +1,8 @@ + diff --git a/source/app/views/urls/new.html.erb b/source/app/views/urls/new.html.erb new file mode 100644 index 0000000..a51c156 --- /dev/null +++ b/source/app/views/urls/new.html.erb @@ -0,0 +1,4 @@ +<%= form_for @url do |f| %> + <%= f.text_field :long_url, placeholder: "Paste url text here" %> + <%= f.submit "Shorten" %> +<% end %> diff --git a/source/config/routes.rb b/source/config/routes.rb index 3f66539..e3efb2d 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,56 +1,4 @@ Rails.application.routes.draw do - # The priority is based upon order of creation: first created -> highest priority. - # See how all your routes lay out with "rake routes". - - # You can have the root of your site routed with "root" - # root 'welcome#index' - - # Example of regular route: - # get 'products/:id' => 'catalog#view' - - # Example of named route that can be invoked with purchase_url(id: product.id) - # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase - - # Example resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Example resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Example resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Example resource route with more complex sub-resources: - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', on: :collection - # end - # end - - # Example resource route with concerns: - # concern :toggleable do - # post 'toggle' - # end - # resources :posts, concerns: :toggleable - # resources :photos, concerns: :toggleable - - # Example resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end + resources :urls, only: [:index, :new, :create] + get "/:short_url", to: "urls#show", as: "short_url" end diff --git a/source/db/migrate/20180514210613_create_urls.rb b/source/db/migrate/20180514210613_create_urls.rb new file mode 100644 index 0000000..79c16d4 --- /dev/null +++ b/source/db/migrate/20180514210613_create_urls.rb @@ -0,0 +1,10 @@ +class CreateUrls < ActiveRecord::Migration + def change + create_table :urls do |t| + t.string :long_url + t.string :short_url + + t.timestamps + end + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb new file mode 100644 index 0000000..028933b --- /dev/null +++ b/source/db/schema.rb @@ -0,0 +1,23 @@ +# 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: 20180514210613) do + + create_table "urls", force: true do |t| + t.string "long_url" + t.string "short_url" + 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 b030da1bb5941a91b61eb1eb19db358f9a9559ad Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 09:45:50 -0400 Subject: [PATCH 02/15] Release 1: Add a Counter. --- source/app/controllers/urls_controller.rb | 3 +++ source/app/models/url.rb | 2 +- source/db/migrate/20180515133521_add_click_count_to_urls.rb | 5 +++++ source/db/schema.rb | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 source/db/migrate/20180515133521_add_click_count_to_urls.rb diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index aa3aca2..61bb492 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -19,6 +19,9 @@ def create end def show + @url.click_count += 1 + @url.save + redirect_to "http://#{@url.long_url}" end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 6224902..700f855 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,6 +1,6 @@ class Url < ActiveRecord::Base validates :short_url, uniqueness: true - before_save :create_short_url + before_create :create_short_url def create_short_url begin diff --git a/source/db/migrate/20180515133521_add_click_count_to_urls.rb b/source/db/migrate/20180515133521_add_click_count_to_urls.rb new file mode 100644 index 0000000..93b0e1f --- /dev/null +++ b/source/db/migrate/20180515133521_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 index 028933b..0299d4f 100644 --- a/source/db/schema.rb +++ b/source/db/schema.rb @@ -11,13 +11,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180514210613) do +ActiveRecord::Schema.define(version: 20180515133521) do create_table "urls", force: true do |t| t.string "long_url" t.string "short_url" t.datetime "created_at" t.datetime "updated_at" + t.integer "click_count", default: 0 end end From cdf5da5b2d32682499f6d9b8b0cf18536a380a78 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 11:46:02 -0400 Subject: [PATCH 03/15] Release 2: Add Validations. --- source/app/controllers/urls_controller.rb | 2 +- source/app/models/url.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 61bb492..1e86a99 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -10,7 +10,7 @@ def new end def create - @url = Url.new(url_params) + @url = Url.find_or_initialize_by(url_params) if @url.save redirect_to urls_path else diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 700f855..2f21716 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,5 +1,9 @@ class Url < ActiveRecord::Base + validates :long_url, presence: true validates :short_url, uniqueness: true + + validate :uri_properly_formatted + before_create :create_short_url def create_short_url @@ -9,4 +13,17 @@ def create_short_url self.short_url = short_url end + + def compliant? + new_uri = URI.parse(self.long_url) + new_uri.is_a?(URI::HTTP) && !new_uri.host.nil? + rescue URI::InvalidURIError + false + end + + def uri_properly_formatted + unless self.compliant? + errors.add(:long_url, "url is invalid, must include 'http://' or 'https://'") + end + end end From b79d14e796fbbb23c452efe471eacb132a31cb3d Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 13:17:23 -0400 Subject: [PATCH 04/15] Release 3: Add Error Handling. --- source/app/assets/stylesheets/application.css | 4 ++++ source/app/controllers/urls_controller.rb | 1 + source/app/models/url.rb | 2 +- source/app/views/layouts/_error_messages.html.erb | 5 +++++ source/app/views/urls/index.html.erb | 2 ++ source/app/views/urls/new.html.erb | 2 ++ 6 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 source/app/views/layouts/_error_messages.html.erb diff --git a/source/app/assets/stylesheets/application.css b/source/app/assets/stylesheets/application.css index a443db3..bab7b71 100644 --- a/source/app/assets/stylesheets/application.css +++ b/source/app/assets/stylesheets/application.css @@ -13,3 +13,7 @@ *= require_tree . *= require_self */ + +div#flash_error { + color: red; +} diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 1e86a99..d4d5a15 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -14,6 +14,7 @@ def create if @url.save redirect_to urls_path else + flash[:error] = @url.errors.full_messages redirect_to new_url_path(@url) end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 2f21716..c9073db 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -23,7 +23,7 @@ def compliant? def uri_properly_formatted unless self.compliant? - errors.add(:long_url, "url is invalid, must include 'http://' or 'https://'") + errors.add(:long_url, "must include 'http://' or 'https://'") end end end diff --git a/source/app/views/layouts/_error_messages.html.erb b/source/app/views/layouts/_error_messages.html.erb new file mode 100644 index 0000000..ff5c2a6 --- /dev/null +++ b/source/app/views/layouts/_error_messages.html.erb @@ -0,0 +1,5 @@ +<% if flash[:error] %> + <%= content_tag :div, flash[:error], id: "flash_error" do %> + <%= flash[:error].join(", ") %> + <% end %> +<% end %> diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index bcb1aca..90759a6 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -1,3 +1,5 @@ +<%= link_to "Create a new short link", new_url_path %> +
    <% @urls.each do |url| %>
  • diff --git a/source/app/views/urls/new.html.erb b/source/app/views/urls/new.html.erb index a51c156..5b53ee5 100644 --- a/source/app/views/urls/new.html.erb +++ b/source/app/views/urls/new.html.erb @@ -1,3 +1,5 @@ +<%= render '/layouts/error_messages' %> + <%= form_for @url do |f| %> <%= f.text_field :long_url, placeholder: "Paste url text here" %> <%= f.submit "Shorten" %> From 6560b8ebba7d099f37a4bee578032bc44ba63e62 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 13:21:07 -0400 Subject: [PATCH 05/15] Add bcrypt gem. --- source/Gemfile | 2 +- source/Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/Gemfile b/source/Gemfile index 633a5c0..f4cef96 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -27,7 +27,7 @@ gem 'sdoc', '~> 0.4.0', group: :doc gem 'spring', group: :development # Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' +gem 'bcrypt', '~> 3.1.7' # Use unicorn as the app server # gem 'unicorn' diff --git a/source/Gemfile.lock b/source/Gemfile.lock index ab6209f..4a09a21 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -28,6 +28,7 @@ GEM thread_safe (~> 0.1) tzinfo (~> 1.1) arel (5.0.1.20140414130214) + bcrypt (3.1.11) builder (3.2.2) coderay (1.1.2) coffee-rails (4.0.1) @@ -130,6 +131,7 @@ PLATFORMS ruby DEPENDENCIES + bcrypt (~> 3.1.7) coffee-rails (~> 4.0.0) jbuilder (~> 2.0) jquery-rails From 67a7eea108efd911e45c357cc4fc4b825841feaf Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 13:24:37 -0400 Subject: [PATCH 06/15] Create users table. --- source/app/models/user.rb | 2 ++ source/db/migrate/20180515172345_create_users.rb | 10 ++++++++++ source/spec/models/user_spec.rb | 5 +++++ 3 files changed, 17 insertions(+) create mode 100644 source/app/models/user.rb create mode 100644 source/db/migrate/20180515172345_create_users.rb create mode 100644 source/spec/models/user_spec.rb diff --git a/source/app/models/user.rb b/source/app/models/user.rb new file mode 100644 index 0000000..4a57cf0 --- /dev/null +++ b/source/app/models/user.rb @@ -0,0 +1,2 @@ +class User < ActiveRecord::Base +end diff --git a/source/db/migrate/20180515172345_create_users.rb b/source/db/migrate/20180515172345_create_users.rb new file mode 100644 index 0000000..7b9d598 --- /dev/null +++ b/source/db/migrate/20180515172345_create_users.rb @@ -0,0 +1,10 @@ +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + t.string :username + t.string :password_digest + + t.timestamps + end + end +end diff --git a/source/spec/models/user_spec.rb b/source/spec/models/user_spec.rb new file mode 100644 index 0000000..0bc0e60 --- /dev/null +++ b/source/spec/models/user_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe User, :type => :model do + pending "add some examples to (or delete) #{__FILE__}" +end From f7d1013c2147ce64710499c5abbed4525e06a2a5 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 13:25:37 -0400 Subject: [PATCH 07/15] Add user routes. --- source/config/routes.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/config/routes.rb b/source/config/routes.rb index e3efb2d..5e0b8de 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,4 +1,7 @@ Rails.application.routes.draw do resources :urls, only: [:index, :new, :create] + get "/:short_url", to: "urls#show", as: "short_url" + + resources :users, only: [:new, :create, :show] end From 0393ea6782b81b12e938b93d11433a60da13a9a8 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 13:26:12 -0400 Subject: [PATCH 08/15] Create view pages. --- source/app/views/users/new.html.erb | 0 source/app/views/users/show.html.erb | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/app/views/users/new.html.erb create mode 100644 source/app/views/users/show.html.erb diff --git a/source/app/views/users/new.html.erb b/source/app/views/users/new.html.erb new file mode 100644 index 0000000..e69de29 diff --git a/source/app/views/users/show.html.erb b/source/app/views/users/show.html.erb new file mode 100644 index 0000000..e69de29 From 1610a6a50370a49b6d6f3c6beb6650d104c1d2ce Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:43:19 -0400 Subject: [PATCH 09/15] Create user login and logout. --- source/app/views/sessions/new.html.erb | 5 +++++ source/config/routes.rb | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 source/app/views/sessions/new.html.erb diff --git a/source/app/views/sessions/new.html.erb b/source/app/views/sessions/new.html.erb new file mode 100644 index 0000000..bcc1160 --- /dev/null +++ b/source/app/views/sessions/new.html.erb @@ -0,0 +1,5 @@ +<%= form_for :user do |f| %> + Username: <%= f.text_field :username %> + Password: <%= f.password_field :password %> + <%= f.submit "Login" %> +<% end %> diff --git a/source/config/routes.rb b/source/config/routes.rb index 5e0b8de..59d4b24 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,7 +1,11 @@ Rails.application.routes.draw do resources :urls, only: [:index, :new, :create] + resources :users, only: [:create, :show] - get "/:short_url", to: "urls#show", as: "short_url" + get "/login", to: "sessions#new", as: "log_in" + post "/login", to: "sessions#create" + get "/logout", to: "sessions#destroy", as: "log_out" + get "/signup", to: "users#new", as: "signup" - resources :users, only: [:new, :create, :show] + get "/:short_url", to: "urls#show", as: "short_url" end From 49cbcab3383d6822172af9785a40d8d3e2089fcf Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:44:22 -0400 Subject: [PATCH 10/15] Finish sessions controller. --- source/app/controllers/sessions_controller.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/app/controllers/sessions_controller.rb b/source/app/controllers/sessions_controller.rb index 16d11b5..2f31ba1 100644 --- a/source/app/controllers/sessions_controller.rb +++ b/source/app/controllers/sessions_controller.rb @@ -1,2 +1,16 @@ class SessionsController < ApplicationController + def create + user = User.find_by(username: params[:user][:username]) + if user && user.authenticate(params[:user][:password]) + session[:user_id] = user.id + redirect_to urls_path + else + redirect_to log_in_path + end + end + + def destroy + session[:user_id] = nil + redirect_to log_in_path + end end From 75f95c5e2e7093d784be4cdd43fff10add630b06 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:46:14 -0400 Subject: [PATCH 11/15] Add logout link. --- source/app/views/layouts/_navigation.html.erb | 4 ++++ source/app/views/layouts/application.html.erb | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 source/app/views/layouts/_navigation.html.erb diff --git a/source/app/views/layouts/_navigation.html.erb b/source/app/views/layouts/_navigation.html.erb new file mode 100644 index 0000000..96f1c56 --- /dev/null +++ b/source/app/views/layouts/_navigation.html.erb @@ -0,0 +1,4 @@ +<% if session[:user_id] %> + <%= link_to "Profile", user_path(session[:user_id]) %>
    + <%= link_to "Logout", log_out_path %>
    +<% end %> diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index f946432..72debd1 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -8,6 +8,8 @@ +<%= render "/layouts/navigation" %> + <%= yield %> From a9ceccbcdb045cc05016a245bf0db73833e48d70 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:47:59 -0400 Subject: [PATCH 12/15] Add login and sign up links when logged out. --- source/app/views/layouts/_navigation.html.erb | 3 +++ source/config/routes.rb | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/app/views/layouts/_navigation.html.erb b/source/app/views/layouts/_navigation.html.erb index 96f1c56..e89763e 100644 --- a/source/app/views/layouts/_navigation.html.erb +++ b/source/app/views/layouts/_navigation.html.erb @@ -1,4 +1,7 @@ <% if session[:user_id] %> <%= link_to "Profile", user_path(session[:user_id]) %>
    <%= link_to "Logout", log_out_path %>
    +<% else %> + <%= link_to "Login", log_in_path %> or <%= link_to "Signup", sign_up_path %> + <% end %> diff --git a/source/config/routes.rb b/source/config/routes.rb index 59d4b24..19af0b9 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -5,7 +5,7 @@ get "/login", to: "sessions#new", as: "log_in" post "/login", to: "sessions#create" get "/logout", to: "sessions#destroy", as: "log_out" - get "/signup", to: "users#new", as: "signup" + get "/signup", to: "users#new", as: "sign_up" get "/:short_url", to: "urls#show", as: "short_url" end From 5f31557c9f10b7b053aaca29ee3fc0cfe93d7687 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:48:32 -0400 Subject: [PATCH 13/15] Create sign up page. --- source/app/views/users/new.html.erb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/app/views/users/new.html.erb b/source/app/views/users/new.html.erb index e69de29..a95c1c7 100644 --- a/source/app/views/users/new.html.erb +++ b/source/app/views/users/new.html.erb @@ -0,0 +1,7 @@ +

    Sign up!

    +<%= form_for @user do |f| %> + Username: <%= f.text_field :username %> + Password: <%= f.password_field :password %> + Password Confirmation: <%= f.password_field :password_confirmation %> + <%= f.submit "Sign up" %> +<% end %> From 13b00eae0652df854330fef51e11326699aad37d Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 15:48:55 -0400 Subject: [PATCH 14/15] Update user model. --- source/app/models/user.rb | 1 + source/db/schema.rb | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/source/app/models/user.rb b/source/app/models/user.rb index 4a57cf0..40f0705 100644 --- a/source/app/models/user.rb +++ b/source/app/models/user.rb @@ -1,2 +1,3 @@ class User < ActiveRecord::Base + has_secure_password end diff --git a/source/db/schema.rb b/source/db/schema.rb index 0299d4f..8b2b6b4 100644 --- a/source/db/schema.rb +++ b/source/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180515133521) do +ActiveRecord::Schema.define(version: 20180515172345) do create_table "urls", force: true do |t| t.string "long_url" @@ -21,4 +21,11 @@ t.integer "click_count", default: 0 end + create_table "users", force: true do |t| + t.string "username" + t.string "password_digest" + t.datetime "created_at" + t.datetime "updated_at" + end + end From c2b2185c0b086502b7ca189aba6a8c9887f76b35 Mon Sep 17 00:00:00 2001 From: Andrew Bonner Date: Tue, 15 May 2018 16:06:13 -0400 Subject: [PATCH 15/15] Extra credit: Add User Authentication. --- source/app/controllers/urls_controller.rb | 2 +- source/app/controllers/users_controller.rb | 29 +++++++++++++++++++ source/app/models/url.rb | 2 ++ source/app/models/user.rb | 4 +++ source/app/views/layouts/_navigation.html.erb | 9 ++++-- source/app/views/urls/index.html.erb | 2 +- source/app/views/users/show.html.erb | 9 ++++++ .../20180515194957_add_user_id_to_urls.rb | 5 ++++ source/db/schema.rb | 3 +- 9 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 source/db/migrate/20180515194957_add_user_id_to_urls.rb diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index d4d5a15..e00c00f 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -23,7 +23,7 @@ def show @url.click_count += 1 @url.save - redirect_to "http://#{@url.long_url}" + redirect_to "#{@url.long_url}" end private diff --git a/source/app/controllers/users_controller.rb b/source/app/controllers/users_controller.rb index 3e74dea..6433842 100644 --- a/source/app/controllers/users_controller.rb +++ b/source/app/controllers/users_controller.rb @@ -1,2 +1,31 @@ class UsersController < ApplicationController + def new + @user = User.new + end + + def create + @user = User.new(user_params) + if @user.save + session[:user_id] = @user.id + redirect_to urls_path + else + flash[:error] = @url.errors.full_messages + redirect_to new_user_path(@user) + end + end + + def show + @user = User.find_by(id: params[:id]) + if @user.id == session[:user_id] + render "show" + else + redirect_to log_in_path + end + end + + private + + def user_params + params.require(:user).permit(:username, :password, :password_confirmation) + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index c9073db..6c1ca3b 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,4 +1,6 @@ class Url < ActiveRecord::Base + belongs_to :user + validates :long_url, presence: true validates :short_url, uniqueness: true diff --git a/source/app/models/user.rb b/source/app/models/user.rb index 40f0705..b96e73e 100644 --- a/source/app/models/user.rb +++ b/source/app/models/user.rb @@ -1,3 +1,7 @@ class User < ActiveRecord::Base has_secure_password + + validates :username, uniqueness: true + + has_many :urls end diff --git a/source/app/views/layouts/_navigation.html.erb b/source/app/views/layouts/_navigation.html.erb index e89763e..a71a50c 100644 --- a/source/app/views/layouts/_navigation.html.erb +++ b/source/app/views/layouts/_navigation.html.erb @@ -1,7 +1,10 @@ <% if session[:user_id] %> - <%= link_to "Profile", user_path(session[:user_id]) %>
    - <%= link_to "Logout", log_out_path %>
    +
      +
    • <%= link_to "Main", urls_path %>
    • +
    • <%= link_to "Profile", user_path(session[:user_id]) %>
    • +
    • <%= link_to "Logout", log_out_path %>
    • +
    + <% else %> <%= link_to "Login", log_in_path %> or <%= link_to "Signup", sign_up_path %> - <% end %> diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index 90759a6..af2b464 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -3,7 +3,7 @@
      <% @urls.each do |url| %>
    • - <%= url.long_url %>
      + <%= link_to "#{url.long_url}", url.long_url %>
      <%= link_to "#{short_url_url(url.short_url)}", short_url_path(url.short_url) %>
    • <% end %> diff --git a/source/app/views/users/show.html.erb b/source/app/views/users/show.html.erb index e69de29..41d5ee6 100644 --- a/source/app/views/users/show.html.erb +++ b/source/app/views/users/show.html.erb @@ -0,0 +1,9 @@ +Username: <%= @user.username %> +
        + <% @user.urls.each do |url| %> +
      • + Original url: <%= link_to "#{url.long_url}", url.long_url %>
        + Short url: <%= link_to "#{short_url_url(url.short_url)}", short_url_path(url.short_url) %> +
      • + <% end %> +
      diff --git a/source/db/migrate/20180515194957_add_user_id_to_urls.rb b/source/db/migrate/20180515194957_add_user_id_to_urls.rb new file mode 100644 index 0000000..b1f5ace --- /dev/null +++ b/source/db/migrate/20180515194957_add_user_id_to_urls.rb @@ -0,0 +1,5 @@ +class AddUserIdToUrls < ActiveRecord::Migration + def change + add_column :urls, :user_id, :integer + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index 8b2b6b4..9520920 100644 --- a/source/db/schema.rb +++ b/source/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180515172345) do +ActiveRecord::Schema.define(version: 20180515194957) do create_table "urls", force: true do |t| t.string "long_url" @@ -19,6 +19,7 @@ t.datetime "created_at" t.datetime "updated_at" t.integer "click_count", default: 0 + t.integer "user_id" end create_table "users", force: true do |t|