From 86c668541cb300763a5bd60958e716ad60f70183 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 13:25:58 -0400 Subject: [PATCH 01/12] before_save shortens the url, new and destroy functionality --- source/Gemfile.lock | 3 + .../app/assets/stylesheets/scaffolds.css.scss | 69 ++++++++ source/app/controllers/urls_controller.rb | 27 +++ source/app/models/url.rb | 9 + source/app/views/urls/.index.html.erb.swp | Bin 0 -> 12288 bytes source/app/views/urls/_form.html.erb | 10 ++ source/app/views/urls/edit.html.erb | 6 + source/app/views/urls/index.html.erb | 28 +++ source/app/views/urls/index.json.jbuilder | 4 + source/app/views/urls/new.html.erb | 5 + source/app/views/urls/show.html.erb | 6 + source/app/views/urls/show.json.jbuilder | 1 + source/config/routes.rb | 3 + source/db/migrate/20150610161621_url.rb | 4 + .../db/migrate/20150610172307_create_urls.rb | 12 ++ source/db/schema.rb | 23 +++ .../spec/controllers/urls_controller_spec.rb | 159 ++++++++++++++++++ source/spec/helpers/urls_helper_spec.rb | 15 ++ source/spec/models/url_spec.rb | 5 + source/spec/requests/urls_spec.rb | 10 ++ source/spec/routing/urls_routing_spec.rb | 35 ++++ source/spec/views/urls/edit.html.erb_spec.rb | 14 ++ source/spec/views/urls/index.html.erb_spec.rb | 14 ++ source/spec/views/urls/new.html.erb_spec.rb | 14 ++ source/spec/views/urls/show.html.erb_spec.rb | 11 ++ 25 files changed, 487 insertions(+) create mode 100644 source/app/assets/stylesheets/scaffolds.css.scss create mode 100644 source/app/models/url.rb create mode 100644 source/app/views/urls/.index.html.erb.swp create mode 100644 source/app/views/urls/_form.html.erb create mode 100644 source/app/views/urls/edit.html.erb create mode 100644 source/app/views/urls/index.html.erb create mode 100644 source/app/views/urls/index.json.jbuilder create mode 100644 source/app/views/urls/new.html.erb create mode 100644 source/app/views/urls/show.html.erb create mode 100644 source/app/views/urls/show.json.jbuilder create mode 100644 source/db/migrate/20150610161621_url.rb create mode 100644 source/db/migrate/20150610172307_create_urls.rb create mode 100644 source/db/schema.rb create mode 100644 source/spec/controllers/urls_controller_spec.rb create mode 100644 source/spec/helpers/urls_helper_spec.rb create mode 100644 source/spec/models/url_spec.rb create mode 100644 source/spec/requests/urls_spec.rb create mode 100644 source/spec/routing/urls_routing_spec.rb create mode 100644 source/spec/views/urls/edit.html.erb_spec.rb create mode 100644 source/spec/views/urls/index.html.erb_spec.rb create mode 100644 source/spec/views/urls/new.html.erb_spec.rb create mode 100644 source/spec/views/urls/show.html.erb_spec.rb diff --git a/source/Gemfile.lock b/source/Gemfile.lock index fcf8b98..e775187 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -136,3 +136,6 @@ DEPENDENCIES sqlite3 turbolinks uglifier (>= 1.3.0) + +BUNDLED WITH + 1.10.2 diff --git a/source/app/assets/stylesheets/scaffolds.css.scss b/source/app/assets/stylesheets/scaffolds.css.scss new file mode 100644 index 0000000..6ec6a8f --- /dev/null +++ b/source/app/assets/stylesheets/scaffolds.css.scss @@ -0,0 +1,69 @@ +body { + background-color: #fff; + color: #333; + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { + color: #000; + &:visited { + color: #666; + } + &:hover { + color: #fff; + background-color: #000; + } +} + +div { + &.field, &.actions { + margin-bottom: 10px; + } +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0px; + background-color: #c00; + color: #fff; + } + ul li { + font-size: 12px; + list-style: square; + } +} diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index ef26710..0e2b993 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,2 +1,29 @@ class UrlsController < ApplicationController + + def index + @urls = Url.all() + end + + def show + @url = Url.find(params[:id]) + end + + def create + @url = Url.new(params.require(:url).permit(:address)) + @url.save + redirect_to_index + end + + def new + @url = Url.new + end + + def destroy + Url.find(params[:id]).destroy + redirect_to_index + end + + def redirect_to_index + redirect_to urls_path + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb new file mode 100644 index 0000000..d1092af --- /dev/null +++ b/source/app/models/url.rb @@ -0,0 +1,9 @@ +class Url < ActiveRecord::Base + before_save :shorten_address + validates_uniqueness_of :unique_key + + def shorten_address + self.unique_key = 8.times.map { [*'0'..'9', *'a'..'z'].sample }.join + end + +end diff --git a/source/app/views/urls/.index.html.erb.swp b/source/app/views/urls/.index.html.erb.swp new file mode 100644 index 0000000000000000000000000000000000000000..c87caca212a2562aad1f50b317e9008a8ba31fe7 GIT binary patch literal 12288 zcmeI2J#P~+7{^^Uh5`Z>#PX1;3P>fFl7T9^gqOAhsD+^~f~h#M%bjvLpU%FfDFwa* zGwjT4dOf{$uodfp4T?OmL7XbRU5i{lsp-5kHU)RG0X8tsK;bqo z&rOQPmD##~Jyp3tXHKt;i{w5wzy{a=8(;%$fDNz#Hoyk{Qv)uW5KpnUW99zNm-WP< zx@>aA2G{@_U;}J`4X^<=zy{a=8(;%$fDQbE2BZ?=_M{N+fdBu0|M&lwlR|t3pTGz3 z2D}0K#3xwLGcLP^t$TxJA8@Nf*&{TZpie`_I71 zPNLg_2#+13hW-(aY0|0kfxd-y)~3}+=b9u)4fz|{7?K@?$D4HBch+pYqp8)R`u^x& z<_a8A?@jAxcB=i;nisTnxfx>3m~Mvp+C@e+si}0Lot_~joov!0>Y8*j&ihTO-oTQE zrXXA7`dXD9BQZ9kj>xg7Vuu78)q$0ZNO$SaLsud*7_IHMv6!ePmCCiXhhoD0ox{n< zmX_U!l%ZV=+C? + +
+

Url: <%= f.text_field :address %>

+

+ +
+ <%= f.submit %> +
+<% end %> diff --git a/source/app/views/urls/edit.html.erb b/source/app/views/urls/edit.html.erb new file mode 100644 index 0000000..e52fdf4 --- /dev/null +++ b/source/app/views/urls/edit.html.erb @@ -0,0 +1,6 @@ +

Editing url

+ +<%= render 'form' %> + +<%= link_to 'Show', @url %> | +<%= link_to 'Back', urls_path %> diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb new file mode 100644 index 0000000..5fdbb93 --- /dev/null +++ b/source/app/views/urls/index.html.erb @@ -0,0 +1,28 @@ +

Listing Urls

+ + + + + + + + + + <% @urls.each do |url| %> + + + + + + + + <% end %> + <% if @urls.size == 0 %> +

There are no urls

+ <% end %> + +
<%= url.address %><%= root_url + url.unique_key %><%= link_to 'Show', url %><%= link_to 'Edit', edit_url_path(url) %><%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %>
+ +
+ +<%= link_to 'New Url', new_url_path %> diff --git a/source/app/views/urls/index.json.jbuilder b/source/app/views/urls/index.json.jbuilder new file mode 100644 index 0000000..8291267 --- /dev/null +++ b/source/app/views/urls/index.json.jbuilder @@ -0,0 +1,4 @@ +json.array!(@urls) do |url| + json.extract! url, :id + json.url url_url(url, format: :json) +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..7e711d5 --- /dev/null +++ b/source/app/views/urls/new.html.erb @@ -0,0 +1,5 @@ +

New url

+ +<%= render 'form' %> + +<%= link_to 'Back', urls_path %> diff --git a/source/app/views/urls/show.html.erb b/source/app/views/urls/show.html.erb new file mode 100644 index 0000000..d17fbcf --- /dev/null +++ b/source/app/views/urls/show.html.erb @@ -0,0 +1,6 @@ +

<%= notice %>

+ +

<%= @url.address %>

+ +<%= link_to 'Edit', edit_url_path(@url) %> | +<%= link_to 'Back', urls_path %> diff --git a/source/app/views/urls/show.json.jbuilder b/source/app/views/urls/show.json.jbuilder new file mode 100644 index 0000000..7e2f9a0 --- /dev/null +++ b/source/app/views/urls/show.json.jbuilder @@ -0,0 +1 @@ +json.extract! @url, :id, :created_at, :updated_at diff --git a/source/config/routes.rb b/source/config/routes.rb index 3f66539..7c63c77 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,4 +1,7 @@ Rails.application.routes.draw do + root 'urls#index' + 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/20150610161621_url.rb b/source/db/migrate/20150610161621_url.rb new file mode 100644 index 0000000..a32632c --- /dev/null +++ b/source/db/migrate/20150610161621_url.rb @@ -0,0 +1,4 @@ +class Url < ActiveRecord::Migration + def change + end +end diff --git a/source/db/migrate/20150610172307_create_urls.rb b/source/db/migrate/20150610172307_create_urls.rb new file mode 100644 index 0000000..2493971 --- /dev/null +++ b/source/db/migrate/20150610172307_create_urls.rb @@ -0,0 +1,12 @@ +class CreateUrls < ActiveRecord::Migration + def change + drop_table :urls do |d| + end + create_table :urls do |t| + t.string :address + t.string :unique_key + + t.timestamps + end + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb new file mode 100644 index 0000000..a381c99 --- /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: 20150610172307) do + + create_table "urls", force: true do |t| + t.string "address" + t.string "unique_key" + t.datetime "created_at" + t.datetime "updated_at" + end + +end diff --git a/source/spec/controllers/urls_controller_spec.rb b/source/spec/controllers/urls_controller_spec.rb new file mode 100644 index 0000000..7014ddd --- /dev/null +++ b/source/spec/controllers/urls_controller_spec.rb @@ -0,0 +1,159 @@ +require 'rails_helper' + +# This spec was generated by rspec-rails when you ran the scaffold generator. +# It demonstrates how one might use RSpec to specify the controller code that +# was generated by Rails when you ran the scaffold generator. +# +# It assumes that the implementation code is generated by the rails scaffold +# generator. If you are using any extension libraries to generate different +# controller code, this generated spec may or may not pass. +# +# It only uses APIs available in rails and/or rspec-rails. There are a number +# of tools you can use to make these specs even more expressive, but we're +# sticking to rails and rspec-rails APIs to keep things simple and stable. +# +# Compared to earlier versions of this generator, there is very limited use of +# stubs and message expectations in this spec. Stubs are only used when there +# is no simpler way to get a handle on the object needed for the example. +# Message expectations are only used when there is no simpler way to specify +# that an instance is receiving a specific message. + +RSpec.describe UrlsController, :type => :controller do + + # This should return the minimal set of attributes required to create a valid + # Url. As you add validations to Url, be sure to + # adjust the attributes here as well. + let(:valid_attributes) { + skip("Add a hash of attributes valid for your model") + } + + let(:invalid_attributes) { + skip("Add a hash of attributes invalid for your model") + } + + # This should return the minimal set of values that should be in the session + # in order to pass any filters (e.g. authentication) defined in + # UrlsController. Be sure to keep this updated too. + let(:valid_session) { {} } + + describe "GET index" do + it "assigns all urls as @urls" do + url = Url.create! valid_attributes + get :index, {}, valid_session + expect(assigns(:urls)).to eq([url]) + end + end + + describe "GET show" do + it "assigns the requested url as @url" do + url = Url.create! valid_attributes + get :show, {:id => url.to_param}, valid_session + expect(assigns(:url)).to eq(url) + end + end + + describe "GET new" do + it "assigns a new url as @url" do + get :new, {}, valid_session + expect(assigns(:url)).to be_a_new(Url) + end + end + + describe "GET edit" do + it "assigns the requested url as @url" do + url = Url.create! valid_attributes + get :edit, {:id => url.to_param}, valid_session + expect(assigns(:url)).to eq(url) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Url" do + expect { + post :create, {:url => valid_attributes}, valid_session + }.to change(Url, :count).by(1) + end + + it "assigns a newly created url as @url" do + post :create, {:url => valid_attributes}, valid_session + expect(assigns(:url)).to be_a(Url) + expect(assigns(:url)).to be_persisted + end + + it "redirects to the created url" do + post :create, {:url => valid_attributes}, valid_session + expect(response).to redirect_to(Url.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved url as @url" do + post :create, {:url => invalid_attributes}, valid_session + expect(assigns(:url)).to be_a_new(Url) + end + + it "re-renders the 'new' template" do + post :create, {:url => invalid_attributes}, valid_session + expect(response).to render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + let(:new_attributes) { + skip("Add a hash of attributes valid for your model") + } + + it "updates the requested url" do + url = Url.create! valid_attributes + put :update, {:id => url.to_param, :url => new_attributes}, valid_session + url.reload + skip("Add assertions for updated state") + end + + it "assigns the requested url as @url" do + url = Url.create! valid_attributes + put :update, {:id => url.to_param, :url => valid_attributes}, valid_session + expect(assigns(:url)).to eq(url) + end + + it "redirects to the url" do + url = Url.create! valid_attributes + put :update, {:id => url.to_param, :url => valid_attributes}, valid_session + expect(response).to redirect_to(url) + end + end + + describe "with invalid params" do + it "assigns the url as @url" do + url = Url.create! valid_attributes + put :update, {:id => url.to_param, :url => invalid_attributes}, valid_session + expect(assigns(:url)).to eq(url) + end + + it "re-renders the 'edit' template" do + url = Url.create! valid_attributes + put :update, {:id => url.to_param, :url => invalid_attributes}, valid_session + expect(response).to render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested url" do + url = Url.create! valid_attributes + expect { + delete :destroy, {:id => url.to_param}, valid_session + }.to change(Url, :count).by(-1) + end + + it "redirects to the urls list" do + url = Url.create! valid_attributes + delete :destroy, {:id => url.to_param}, valid_session + expect(response).to redirect_to(urls_url) + end + end + +end diff --git a/source/spec/helpers/urls_helper_spec.rb b/source/spec/helpers/urls_helper_spec.rb new file mode 100644 index 0000000..bbafaf3 --- /dev/null +++ b/source/spec/helpers/urls_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the UrlsHelper. For example: +# +# describe UrlsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe UrlsHelper, :type => :helper do + pending "add some examples to (or delete) #{__FILE__}" +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 diff --git a/source/spec/requests/urls_spec.rb b/source/spec/requests/urls_spec.rb new file mode 100644 index 0000000..cd1976c --- /dev/null +++ b/source/spec/requests/urls_spec.rb @@ -0,0 +1,10 @@ +require 'rails_helper' + +RSpec.describe "Urls", :type => :request do + describe "GET /urls" do + it "works! (now write some real specs)" do + get urls_path + expect(response).to have_http_status(200) + end + end +end diff --git a/source/spec/routing/urls_routing_spec.rb b/source/spec/routing/urls_routing_spec.rb new file mode 100644 index 0000000..d4ec06f --- /dev/null +++ b/source/spec/routing/urls_routing_spec.rb @@ -0,0 +1,35 @@ +require "rails_helper" + +RSpec.describe UrlsController, :type => :routing do + describe "routing" do + + it "routes to #index" do + expect(:get => "/urls").to route_to("urls#index") + end + + it "routes to #new" do + expect(:get => "/urls/new").to route_to("urls#new") + end + + it "routes to #show" do + expect(:get => "/urls/1").to route_to("urls#show", :id => "1") + end + + it "routes to #edit" do + expect(:get => "/urls/1/edit").to route_to("urls#edit", :id => "1") + end + + it "routes to #create" do + expect(:post => "/urls").to route_to("urls#create") + end + + it "routes to #update" do + expect(:put => "/urls/1").to route_to("urls#update", :id => "1") + end + + it "routes to #destroy" do + expect(:delete => "/urls/1").to route_to("urls#destroy", :id => "1") + end + + end +end diff --git a/source/spec/views/urls/edit.html.erb_spec.rb b/source/spec/views/urls/edit.html.erb_spec.rb new file mode 100644 index 0000000..2d8b6a0 --- /dev/null +++ b/source/spec/views/urls/edit.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe "urls/edit", :type => :view do + before(:each) do + @url = assign(:url, Url.create!()) + end + + it "renders the edit url form" do + render + + assert_select "form[action=?][method=?]", url_path(@url), "post" do + end + end +end diff --git a/source/spec/views/urls/index.html.erb_spec.rb b/source/spec/views/urls/index.html.erb_spec.rb new file mode 100644 index 0000000..37fdea5 --- /dev/null +++ b/source/spec/views/urls/index.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe "urls/index", :type => :view do + before(:each) do + assign(:urls, [ + Url.create!(), + Url.create!() + ]) + end + + it "renders a list of urls" do + render + end +end diff --git a/source/spec/views/urls/new.html.erb_spec.rb b/source/spec/views/urls/new.html.erb_spec.rb new file mode 100644 index 0000000..e614f23 --- /dev/null +++ b/source/spec/views/urls/new.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe "urls/new", :type => :view do + before(:each) do + assign(:url, Url.new()) + end + + it "renders new url form" do + render + + assert_select "form[action=?][method=?]", urls_path, "post" do + end + end +end diff --git a/source/spec/views/urls/show.html.erb_spec.rb b/source/spec/views/urls/show.html.erb_spec.rb new file mode 100644 index 0000000..bcd8332 --- /dev/null +++ b/source/spec/views/urls/show.html.erb_spec.rb @@ -0,0 +1,11 @@ +require 'rails_helper' + +RSpec.describe "urls/show", :type => :view do + before(:each) do + @url = assign(:url, Url.create!()) + end + + it "renders attributes in

" do + render + end +end From caddda170765d3a993c93f4a17eeb42633369632 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 13:50:13 -0400 Subject: [PATCH 02/12] complete r0 --- source/app/assets/stylesheets/urls.css.scss | 6 ++++++ source/app/controllers/urls_controller.rb | 18 ++++++++++++++++-- source/app/views/urls/index.html.erb | 4 +--- source/app/views/urls/show.html.erb | 3 +-- source/config/routes.rb | 2 ++ 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/source/app/assets/stylesheets/urls.css.scss b/source/app/assets/stylesheets/urls.css.scss index a4281ec..87f0d17 100644 --- a/source/app/assets/stylesheets/urls.css.scss +++ b/source/app/assets/stylesheets/urls.css.scss @@ -1,3 +1,9 @@ // Place all the styles related to the Urls controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: http://sass-lang.com/ +table { + width: 100%; + td { + border: 1px solid black; + } +} diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 0e2b993..308857c 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,11 +1,12 @@ class UrlsController < ApplicationController + before_action :get_url, only: [:show, :destroy] def index @urls = Url.all() end def show - @url = Url.find(params[:id]) + end def create @@ -19,11 +20,24 @@ def new end def destroy - Url.find(params[:id]).destroy + @url.destroy redirect_to_index end + def expand_link + @url = Url.find_by unique_key: params[:unique_key] + redirect_to_url + end + def redirect_to_index redirect_to urls_path end + + def redirect_to_url + redirect_to @url.address + end + + def get_url + @url = Url.find(params[:id]) + end end diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index 5fdbb93..4dc36e8 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -10,10 +10,8 @@ <% @urls.each do |url| %> + <%= link_to root_url + url.unique_key, url.unique_key %> <%= url.address %> - <%= root_url + url.unique_key %> - <%= link_to 'Show', url %> - <%= link_to 'Edit', edit_url_path(url) %> <%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %> diff --git a/source/app/views/urls/show.html.erb b/source/app/views/urls/show.html.erb index d17fbcf..2e24321 100644 --- a/source/app/views/urls/show.html.erb +++ b/source/app/views/urls/show.html.erb @@ -1,6 +1,5 @@

<%= notice %>

-

<%= @url.address %>

+

<%= root_url + @url.unique_key %>

-<%= link_to 'Edit', edit_url_path(@url) %> | <%= link_to 'Back', urls_path %> diff --git a/source/config/routes.rb b/source/config/routes.rb index 7c63c77..c8bcc01 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -2,6 +2,8 @@ root 'urls#index' resources :urls + get '/:unique_key', to: 'urls#expand_link' + # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". From 1929a8e0943846f51776bb32e61cd0e7e3e8da34 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 14:20:59 -0400 Subject: [PATCH 03/12] r1 complete, click_count added --- source/Gemfile | 1 + source/Gemfile.lock | 87 ++++++++++--------- source/app/controllers/urls_controller.rb | 13 ++- source/app/models/url.rb | 4 +- source/app/views/urls/index.html.erb | 1 + source/db/migrate/20150610180341_add_count.rb | 7 ++ source/db/schema.rb | 3 +- 7 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 source/db/migrate/20150610180341_add_count.rb diff --git a/source/Gemfile b/source/Gemfile index 9627b8b..c379464 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -39,3 +39,4 @@ gem 'spring', group: :development # gem 'debugger', group: [:development, :test] gem 'rspec-rails', group: [:development, :test] + gem 'pry' diff --git a/source/Gemfile.lock b/source/Gemfile.lock index e775187..5517b5e 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -29,32 +29,38 @@ GEM tzinfo (~> 1.1) arel (5.0.1.20140414130214) builder (3.2.2) + coderay (1.1.0) coffee-rails (4.0.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) - coffee-script (2.3.0) + coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.8.0) + coffee-script-source (1.9.1.1) diff-lcs (1.2.5) erubis (2.7.0) - execjs (2.2.1) + execjs (2.5.2) hike (1.2.3) - i18n (0.6.11) - jbuilder (2.2.2) + i18n (0.7.0) + jbuilder (2.2.16) activesupport (>= 3.0.0, < 5) multi_json (~> 1.2) jquery-rails (3.1.2) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) - json (1.8.1) - mail (2.6.1) + json (1.8.3) + mail (2.6.3) mime-types (>= 1.16, < 3) - mime-types (2.4.1) - minitest (5.4.2) - multi_json (1.10.1) - rack (1.5.2) - rack-test (0.6.2) + method_source (0.8.2) + mime-types (2.6.1) + minitest (5.7.0) + multi_json (1.11.0) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.5.3) + rack-test (0.6.3) rack (>= 1.0) rails (4.1.6) actionmailer (= 4.1.6) @@ -71,53 +77,55 @@ GEM activesupport (= 4.1.6) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (10.3.2) - rdoc (4.1.2) + rake (10.4.2) + rdoc (4.2.0) json (~> 1.4) - rspec-core (3.1.6) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rspec-core (3.2.3) + rspec-support (~> 3.2.0) + rspec-expectations (3.2.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-rails (3.1.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) + rspec-support (~> 3.2.0) + rspec-mocks (3.2.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-rails (3.2.3) + actionpack (>= 3.0, < 4.3) + activesupport (>= 3.0, < 4.3) + railties (>= 3.0, < 4.3) + rspec-core (~> 3.2.0) + rspec-expectations (~> 3.2.0) + rspec-mocks (~> 3.2.0) + rspec-support (~> 3.2.0) + rspec-support (3.2.2) sass (3.2.19) - sass-rails (4.0.3) + sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) - sass (~> 3.2.0) - sprockets (~> 2.8, <= 2.11.0) + sass (~> 3.2.2) + sprockets (~> 2.8, < 3.0) sprockets-rails (~> 2.0) sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - spring (1.1.3) - sprockets (2.11.0) + slop (3.6.0) + spring (1.3.6) + sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.2.0) + sprockets-rails (2.3.1) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) - sqlite3 (1.3.9) + sqlite3 (1.3.10) thor (0.19.1) - thread_safe (0.3.4) + thread_safe (0.3.5) tilt (1.4.1) - turbolinks (2.4.0) + turbolinks (2.5.3) coffee-rails tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (2.5.3) + uglifier (2.7.1) execjs (>= 0.3.0) json (>= 1.8.0) @@ -128,6 +136,7 @@ DEPENDENCIES coffee-rails (~> 4.0.0) jbuilder (~> 2.0) jquery-rails + pry rails (= 4.1.6) rspec-rails sass-rails (~> 4.0.3) diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 308857c..05428f2 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -1,14 +1,13 @@ +require 'pry' + class UrlsController < ApplicationController + before_action :get_url, only: [:show, :destroy] def index @urls = Url.all() end - def show - - end - def create @url = Url.new(params.require(:url).permit(:address)) @url.save @@ -34,10 +33,16 @@ def redirect_to_index end def redirect_to_url + @url.click_count += 1 + @url.save redirect_to @url.address end def get_url @url = Url.find(params[:id]) end + + def url_params + params.require(:url).permit(:click_count) + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index d1092af..f88923e 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -3,7 +3,9 @@ class Url < ActiveRecord::Base validates_uniqueness_of :unique_key def shorten_address - self.unique_key = 8.times.map { [*'0'..'9', *'a'..'z'].sample }.join + if self.unique_key.nil? + self.unique_key = 8.times.map { [*'0'..'9', *'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 4dc36e8..59ccd9f 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -12,6 +12,7 @@ <%= link_to root_url + url.unique_key, url.unique_key %> <%= url.address %> + <%= url.click_count %> <%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %> diff --git a/source/db/migrate/20150610180341_add_count.rb b/source/db/migrate/20150610180341_add_count.rb new file mode 100644 index 0000000..2afe41c --- /dev/null +++ b/source/db/migrate/20150610180341_add_count.rb @@ -0,0 +1,7 @@ +class AddCount < ActiveRecord::Migration + def change + change_table :urls do |t| + t.integer :click_count, :default => 0 + end + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index a381c99..b840eb6 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: 20150610172307) do +ActiveRecord::Schema.define(version: 20150610180341) do create_table "urls", force: true do |t| t.string "address" t.string "unique_key" t.datetime "created_at" t.datetime "updated_at" + t.integer "click_count", default: 0 end end From eefd761075530d469792435b86aa73a7cebe50b1 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 14:52:08 -0400 Subject: [PATCH 04/12] Validate url on everything but http request --- source/app/controllers/urls_controller.rb | 11 +++++++++-- source/app/models/url.rb | 11 +++++++++++ source/app/views/urls/_form.html.erb | 12 ++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 05428f2..e4a5060 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -10,8 +10,15 @@ def index def create @url = Url.new(params.require(:url).permit(:address)) - @url.save - redirect_to_index + respond_to do |format| + if @url.save + format.html { redirect_to Url, notice: 'Url was successfully created.' } + format.json { render :show, status: :created, location: @url } + else + format.html { render :new, notice: "Url could not be created" } + format.json { render json: @url.errors, status: :unprocessable_entity } + end + end end def new diff --git a/source/app/models/url.rb b/source/app/models/url.rb index f88923e..c8347fa 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,7 +1,18 @@ +require 'uri' + class Url < ActiveRecord::Base before_save :shorten_address + validates :address, :format => URI::regexp(%w(http https)) validates_uniqueness_of :unique_key + def validate_url + if self.address.match(/^https?:\/\//).nil? + return false + else + validates self.address, :format => URI::regexp(%w(http https)) + end + end + def shorten_address if self.unique_key.nil? self.unique_key = 8.times.map { [*'0'..'9', *'a'..'z'].sample }.join diff --git a/source/app/views/urls/_form.html.erb b/source/app/views/urls/_form.html.erb index 28b36fd..5c5323e 100644 --- a/source/app/views/urls/_form.html.erb +++ b/source/app/views/urls/_form.html.erb @@ -1,5 +1,17 @@ <%= form_for @url, url: {action: "create"} do |f| %> + <% if @url.errors.any? %> +
+

<%= pluralize(@url.errors.count, "error") %> prohibited this url from being saved:

+ +
    + <% @url.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+ <% end %> +

Url: <%= f.text_field :address %>

From 3dc7c092da0394083c59ac39b024157a7b825d61 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 16:24:03 -0400 Subject: [PATCH 05/12] notice on invalid/valid url --- source/app/controllers/urls_controller.rb | 11 +++++------ source/app/models/url.rb | 9 ++++++++- source/app/views/layouts/application.html.erb | 4 ++++ source/app/views/urls/_form.html.erb | 12 ------------ source/app/views/urls/index.html.erb | 2 +- source/config/routes.rb | 4 +++- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index e4a5060..5fbcdf9 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -5,18 +5,17 @@ class UrlsController < ApplicationController before_action :get_url, only: [:show, :destroy] def index - @urls = Url.all() + @urls = Url.all end def create - @url = Url.new(params.require(:url).permit(:address)) + @url = Url.new(url_params) respond_to do |format| if @url.save - format.html { redirect_to Url, notice: 'Url was successfully created.' } - format.json { render :show, status: :created, location: @url } + # binding.pry + format.html { redirect_to urls_path, notice: 'Url was successfully created.' } else format.html { render :new, notice: "Url could not be created" } - format.json { render json: @url.errors, status: :unprocessable_entity } end end end @@ -50,6 +49,6 @@ def get_url end def url_params - params.require(:url).permit(:click_count) + params.require(:url).permit(:address) end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index c8347fa..f2899da 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,15 +1,18 @@ require 'uri' +require "net/http" class Url < ActiveRecord::Base before_save :shorten_address validates :address, :format => URI::regexp(%w(http https)) validates_uniqueness_of :unique_key + # IN PROGRESS def validate_url if self.address.match(/^https?:\/\//).nil? return false else - validates self.address, :format => URI::regexp(%w(http https)) + #self.address, :format => URI::regexp(%w(http https)) + end end @@ -19,4 +22,8 @@ def shorten_address end end + def get_address + address + end + end diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index f946432..564413d 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -8,6 +8,10 @@ +<% if flash[:notice] %> +

<%= flash[:notice]%>

+<% end %> + <%= yield %> diff --git a/source/app/views/urls/_form.html.erb b/source/app/views/urls/_form.html.erb index 5c5323e..28b36fd 100644 --- a/source/app/views/urls/_form.html.erb +++ b/source/app/views/urls/_form.html.erb @@ -1,17 +1,5 @@ <%= form_for @url, url: {action: "create"} do |f| %> - <% if @url.errors.any? %> -
-

<%= pluralize(@url.errors.count, "error") %> prohibited this url from being saved:

- -
    - <% @url.errors.full_messages.each do |message| %> -
  • <%= message %>
  • - <% end %> -
-
- <% end %> -

Url: <%= f.text_field :address %>

diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index 59ccd9f..67bb190 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -16,7 +16,7 @@ <%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %> - <% if @urls.size == 0 %> + <% if @urls.empty? %>

There are no urls

<% end %> diff --git a/source/config/routes.rb b/source/config/routes.rb index c8bcc01..191f9cd 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,9 +1,11 @@ Rails.application.routes.draw do root 'urls#index' - resources :urls + get '/urls', to: 'urls#index' get '/:unique_key', to: 'urls#expand_link' + resources :urls, except: [:show, :edit, :update, :index] + # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". From af39092635bcf1f616d7712111763ce1cf11aac9 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 21:22:09 -0400 Subject: [PATCH 06/12] validate email on submit --- source/Gemfile | 1 + source/Gemfile.lock | 4 ++++ source/app/controllers/urls_controller.rb | 3 +-- source/app/models/url.rb | 23 ++++++++++++++++++----- source/app/views/urls/_form.html.erb | 10 ++++++++++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/source/Gemfile b/source/Gemfile index c379464..cfd10b1 100644 --- a/source/Gemfile +++ b/source/Gemfile @@ -40,3 +40,4 @@ gem 'spring', group: :development gem 'rspec-rails', group: [:development, :test] gem 'pry' + gem 'faraday' diff --git a/source/Gemfile.lock b/source/Gemfile.lock index 5517b5e..0d82162 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -40,6 +40,8 @@ GEM diff-lcs (1.2.5) erubis (2.7.0) execjs (2.5.2) + faraday (0.9.1) + multipart-post (>= 1.2, < 3) hike (1.2.3) i18n (0.7.0) jbuilder (2.2.16) @@ -55,6 +57,7 @@ GEM mime-types (2.6.1) minitest (5.7.0) multi_json (1.11.0) + multipart-post (2.0.0) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -134,6 +137,7 @@ PLATFORMS DEPENDENCIES coffee-rails (~> 4.0.0) + faraday jbuilder (~> 2.0) jquery-rails pry diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 5fbcdf9..e3c7091 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -12,10 +12,9 @@ def create @url = Url.new(url_params) respond_to do |format| if @url.save - # binding.pry format.html { redirect_to urls_path, notice: 'Url was successfully created.' } else - format.html { render :new, notice: "Url could not be created" } + format.html { render :new, notice: @url.errors.messages } end end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index f2899da..26ce73d 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -1,18 +1,30 @@ require 'uri' require "net/http" +require 'faraday' class Url < ActiveRecord::Base before_save :shorten_address - validates :address, :format => URI::regexp(%w(http https)) + validate :validate_url + # validates :address, :format => URI::regexp(%w(http https)) validates_uniqueness_of :unique_key # IN PROGRESS def validate_url if self.address.match(/^https?:\/\//).nil? - return false + errors.add(:address, "needs to be a valid url") else - #self.address, :format => URI::regexp(%w(http https)) + if self.address.match(URI::regexp(%w(http https))).nil? + errors.add(:address, "needs to be a valid url") + end + begin + response = send_http_request(self.address) + if response.status.to_i >= 400 + errors.add(:address, "needs to be a valid url") + end + rescue Faraday::ConnectionFailed + errors.add(:address, "needs to be a valid url") + end end end @@ -22,8 +34,9 @@ def shorten_address end end - def get_address - address + private + def send_http_request url + Faraday.head url end end diff --git a/source/app/views/urls/_form.html.erb b/source/app/views/urls/_form.html.erb index 28b36fd..c423725 100644 --- a/source/app/views/urls/_form.html.erb +++ b/source/app/views/urls/_form.html.erb @@ -1,5 +1,15 @@ <%= form_for @url, url: {action: "create"} do |f| %> + <% if @url.errors.any? %> +
+
    + <% @url.errors.full_messages.each do |message| %> +
  • <%= message %>
  • + <% end %> +
+
+ <% end %> +

Url: <%= f.text_field :address %>

From 23f73b7e2c41b9cc3eb5b7a27059e088374489cf Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Wed, 10 Jun 2015 23:07:46 -0400 Subject: [PATCH 07/12] begin user implementation, with tests --- source/app/controllers/users_controller.rb | 2 + source/app/models/user.rb | 4 ++ source/app/views/layouts/application.html.erb | 2 + source/app/views/users/new.html.erb | 1 + source/config/routes.rb | 3 ++ .../db/migrate/20150611014731_create_users.rb | 9 +++++ source/db/schema.rb | 8 +++- .../spec/controllers/users_controller_spec.rb | 12 ++++++ source/spec/helpers/users_helper_spec.rb | 15 ++++++++ source/spec/models/user_spec.rb | 5 +++ source/spec/views/users/new.html.erb_spec.rb | 5 +++ source/test/models/user_test.rb | 38 +++++++++++++++++++ 12 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 source/app/models/user.rb create mode 100644 source/app/views/users/new.html.erb create mode 100644 source/db/migrate/20150611014731_create_users.rb create mode 100644 source/spec/controllers/users_controller_spec.rb create mode 100644 source/spec/helpers/users_helper_spec.rb create mode 100644 source/spec/models/user_spec.rb create mode 100644 source/spec/views/users/new.html.erb_spec.rb create mode 100644 source/test/models/user_test.rb diff --git a/source/app/controllers/users_controller.rb b/source/app/controllers/users_controller.rb index 3e74dea..2ec9ecc 100644 --- a/source/app/controllers/users_controller.rb +++ b/source/app/controllers/users_controller.rb @@ -1,2 +1,4 @@ class UsersController < ApplicationController + def new + end end diff --git a/source/app/models/user.rb b/source/app/models/user.rb new file mode 100644 index 0000000..3682818 --- /dev/null +++ b/source/app/models/user.rb @@ -0,0 +1,4 @@ +class User < ActiveRecord::Base + VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i + validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX } +end diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index 564413d..27fccf6 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -14,5 +14,7 @@ <%= yield %> +<%= link_to "Sign up", signup_path %> + diff --git a/source/app/views/users/new.html.erb b/source/app/views/users/new.html.erb new file mode 100644 index 0000000..f802b44 --- /dev/null +++ b/source/app/views/users/new.html.erb @@ -0,0 +1 @@ +

Sign up

diff --git a/source/config/routes.rb b/source/config/routes.rb index 191f9cd..bdf8c7e 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,7 +1,10 @@ Rails.application.routes.draw do + get 'users/new' + root 'urls#index' get '/urls', to: 'urls#index' + get '/signup', to: 'users#new' get '/:unique_key', to: 'urls#expand_link' resources :urls, except: [:show, :edit, :update, :index] diff --git a/source/db/migrate/20150611014731_create_users.rb b/source/db/migrate/20150611014731_create_users.rb new file mode 100644 index 0000000..b5dc108 --- /dev/null +++ b/source/db/migrate/20150611014731_create_users.rb @@ -0,0 +1,9 @@ +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + t.string :email + + t.timestamps + end + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index b840eb6..c8e86f7 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: 20150610180341) do +ActiveRecord::Schema.define(version: 20150611014731) do create_table "urls", force: true do |t| t.string "address" @@ -21,4 +21,10 @@ t.integer "click_count", default: 0 end + create_table "users", force: true do |t| + t.string "email" + t.datetime "created_at" + t.datetime "updated_at" + end + end diff --git a/source/spec/controllers/users_controller_spec.rb b/source/spec/controllers/users_controller_spec.rb new file mode 100644 index 0000000..0a86999 --- /dev/null +++ b/source/spec/controllers/users_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe UsersController, type: :controller do + + describe "GET #new" do + it "returns http success" do + get :new + expect(response).to have_http_status(:success) + end + end + +end diff --git a/source/spec/helpers/users_helper_spec.rb b/source/spec/helpers/users_helper_spec.rb new file mode 100644 index 0000000..b2e3444 --- /dev/null +++ b/source/spec/helpers/users_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the UsersHelper. For example: +# +# describe UsersHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe UsersHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/source/spec/models/user_spec.rb b/source/spec/models/user_spec.rb new file mode 100644 index 0000000..47a31bb --- /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 diff --git a/source/spec/views/users/new.html.erb_spec.rb b/source/spec/views/users/new.html.erb_spec.rb new file mode 100644 index 0000000..47b47d3 --- /dev/null +++ b/source/spec/views/users/new.html.erb_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe "users/new.html.erb", type: :view do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/source/test/models/user_test.rb b/source/test/models/user_test.rb new file mode 100644 index 0000000..180b8b3 --- /dev/null +++ b/source/test/models/user_test.rb @@ -0,0 +1,38 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + + def setup + @user = User.new(email: "user@example.com") + end + + test "should be valid" do + assert @user.valid? + end + + test "email should be present" do + @user.email = "" + assert_not @user.valid? + end + + test "email should not be too long" do + @user.email = "a" * 244 + "@example.com" + assert_not @user.valid? + end + + test "email validation should accept valid addresses" do + valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org first.last@foo.jp alice+bob@baz.cn] + valid_addresses.each do |valid_address| + @user.email = valid_address + assert @user.valid?, '#{valid_address.inspect} should be valid' + end + end + + test "email validation should reject invalid addresses" do + invalid_addresses = %w[user@example,com user_at_foo.org user.name@example. foo@bar_baz.com foo@bar+baz.com] + invalid_addresses.each do |invalid_address| + @user.email = invalid_address + assert_not @user.valid?, "#{invalid_address.inspect} should be invalid" + end + end +end From 746ced9ea38bfe5967302faf37bd5aeaaa70daec Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Thu, 11 Jun 2015 09:41:48 -0400 Subject: [PATCH 08/12] add password to user --- source/Gemfile | 2 +- source/Gemfile.lock | 2 ++ source/app/models/user.rb | 8 +++++++- ...20150611132414_add_index_to_users_email.rb | 5 +++++ ...0611133240_add_password_digest_to_users.rb | 5 +++++ source/db/schema.rb | 5 ++++- source/test/models/user_test.rb | 19 ++++++++++++++++++- 7 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 source/db/migrate/20150611132414_add_index_to_users_email.rb create mode 100644 source/db/migrate/20150611133240_add_password_digest_to_users.rb diff --git a/source/Gemfile b/source/Gemfile index cfd10b1..c915f50 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 0d82162..e5dd0c6 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.10) builder (3.2.2) coderay (1.1.0) coffee-rails (4.0.1) @@ -136,6 +137,7 @@ PLATFORMS ruby DEPENDENCIES + bcrypt (~> 3.1.7) coffee-rails (~> 4.0.0) faraday jbuilder (~> 2.0) diff --git a/source/app/models/user.rb b/source/app/models/user.rb index 3682818..d52449d 100644 --- a/source/app/models/user.rb +++ b/source/app/models/user.rb @@ -1,4 +1,10 @@ class User < ActiveRecord::Base + before_save { self.email = email.downcase } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i - validates :email, presence: true, length: { maximum: 255 }, format: { with: VALID_EMAIL_REGEX } + validates :email, presence: true, + length: { maximum: 255 }, + format: { with: VALID_EMAIL_REGEX }, + uniqueness: { case_sensitive: false } + has_secure_password + validates :password, presence: true, length: { minimum: 6 } end diff --git a/source/db/migrate/20150611132414_add_index_to_users_email.rb b/source/db/migrate/20150611132414_add_index_to_users_email.rb new file mode 100644 index 0000000..ca59a67 --- /dev/null +++ b/source/db/migrate/20150611132414_add_index_to_users_email.rb @@ -0,0 +1,5 @@ +class AddIndexToUsersEmail < ActiveRecord::Migration + def change + add_index :users, :email, unique: true + end +end diff --git a/source/db/migrate/20150611133240_add_password_digest_to_users.rb b/source/db/migrate/20150611133240_add_password_digest_to_users.rb new file mode 100644 index 0000000..7ad1f62 --- /dev/null +++ b/source/db/migrate/20150611133240_add_password_digest_to_users.rb @@ -0,0 +1,5 @@ +class AddPasswordDigestToUsers < ActiveRecord::Migration + def change + add_column :users, :password_digest, :string + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index c8e86f7..464b060 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: 20150611014731) do +ActiveRecord::Schema.define(version: 20150611133240) do create_table "urls", force: true do |t| t.string "address" @@ -25,6 +25,9 @@ t.string "email" t.datetime "created_at" t.datetime "updated_at" + t.string "password_digest" end + add_index "users", ["email"], name: "index_users_on_email", unique: true + end diff --git a/source/test/models/user_test.rb b/source/test/models/user_test.rb index 180b8b3..e2fa244 100644 --- a/source/test/models/user_test.rb +++ b/source/test/models/user_test.rb @@ -3,7 +3,7 @@ class UserTest < ActiveSupport::TestCase def setup - @user = User.new(email: "user@example.com") + @user = User.new(email: "user@example.com", password: "foobar", password_confirmation: "foobar") end test "should be valid" do @@ -35,4 +35,21 @@ def setup assert_not @user.valid?, "#{invalid_address.inspect} should be invalid" end end + + test "email addresses should be unique" do + duplicate_user = @user.dup + duplicate_user.email = @user.email.upcase + @user.save + assert_not duplicate_user.valid? + end + + test "password should be present (nonblank)" do + @user.password = @user.password_confirmation = " " * 5 + assert_not @user.valid? + end + + test "password should have a minimum length" do + @user.password = @user.password_confirmation = "a" * 5 + assert_not @user.valid? + end end From e243564bbef079b7936a6889a2fcc1712e20612e Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Thu, 11 Jun 2015 10:13:37 -0400 Subject: [PATCH 09/12] Create user --- source/app/assets/stylesheets/application.css | 6 ++++++ source/app/controllers/urls_controller.rb | 12 ++++++------ source/app/controllers/users_controller.rb | 18 ++++++++++++++++++ source/app/views/layouts/application.html.erb | 7 ++++--- .../app/views/shared/_error_messages.html.erb | 12 ++++++++++++ source/app/views/users/new.html.erb | 19 +++++++++++++++++++ source/config/routes.rb | 1 + .../db/migrate/20150610172307_create_urls.rb | 2 -- 8 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 source/app/views/shared/_error_messages.html.erb diff --git a/source/app/assets/stylesheets/application.css b/source/app/assets/stylesheets/application.css index a443db3..9470714 100644 --- a/source/app/assets/stylesheets/application.css +++ b/source/app/assets/stylesheets/application.css @@ -13,3 +13,9 @@ *= require_tree . *= require_self */ + .field_with_errors { + @extend .has-error; + .form-control { + color: $state-danger-text; + } + } diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index e3c7091..d164757 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -10,12 +10,12 @@ def index def create @url = Url.new(url_params) - respond_to do |format| - if @url.save - format.html { redirect_to urls_path, notice: 'Url was successfully created.' } - else - format.html { render :new, notice: @url.errors.messages } - end + if @url.save + flash[:success] = 'Url was successfully created' + redirect_to urls_path + else + flash[:failure] = 'Url could not be created' + render 'new' end end diff --git a/source/app/controllers/users_controller.rb b/source/app/controllers/users_controller.rb index 2ec9ecc..628c343 100644 --- a/source/app/controllers/users_controller.rb +++ b/source/app/controllers/users_controller.rb @@ -1,4 +1,22 @@ class UsersController < ApplicationController + def new + @user = User.new end + + def create + @user = User.new(user_params) + if @user.save + flash[:success] = "User successfully created" + redirect_to urls_path + else + render 'new' + end + end + + private + + def user_params + params.require(:user).permit(:name, :email, :password, :password_confirmation) + end end diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index 27fccf6..e5a2805 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -8,13 +8,14 @@ -<% if flash[:notice] %> -

<%= flash[:notice]%>

-<% end %> + <% flash.each do |message_type, message| %> +
<%= message %>
+ <% end %> <%= yield %> <%= link_to "Sign up", signup_path %> +<%= debug(params) if Rails.env.development? %> diff --git a/source/app/views/shared/_error_messages.html.erb b/source/app/views/shared/_error_messages.html.erb new file mode 100644 index 0000000..f80053e --- /dev/null +++ b/source/app/views/shared/_error_messages.html.erb @@ -0,0 +1,12 @@ +<% if @user.errors.any? %> +
+
+ The form contains <%= pluralize(@user.errors.count, "error") %>. +
+
    + <% @user.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+
+<% end %> diff --git a/source/app/views/users/new.html.erb b/source/app/views/users/new.html.erb index f802b44..b072893 100644 --- a/source/app/views/users/new.html.erb +++ b/source/app/views/users/new.html.erb @@ -1 +1,20 @@

Sign up

+ +
+
+ <%= form_for(@user) do |f| %> + <%= render 'shared/error_messages' %> + + <%= f.label :email %> + <%= f.text_field :email, class: 'form_control' %> + + <%= f.label :password %> + <%= f.password_field :password, class: 'form_control' %> + + <%= f.label :password_confirmation, "Confirmation" %> + <%= f.password_field :password_confirmation, class: 'form_control' %> + + <%= f.submit "Create my account", class: "btn btn-primary" %> + <% end %> +
+
diff --git a/source/config/routes.rb b/source/config/routes.rb index bdf8c7e..3959150 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -8,6 +8,7 @@ get '/:unique_key', to: 'urls#expand_link' resources :urls, except: [:show, :edit, :update, :index] + resources :users # 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/20150610172307_create_urls.rb b/source/db/migrate/20150610172307_create_urls.rb index 2493971..f03f568 100644 --- a/source/db/migrate/20150610172307_create_urls.rb +++ b/source/db/migrate/20150610172307_create_urls.rb @@ -1,7 +1,5 @@ class CreateUrls < ActiveRecord::Migration def change - drop_table :urls do |d| - end create_table :urls do |t| t.string :address t.string :unique_key From ae252a506a585a8815660f77e9e9ea02589b7ada Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Thu, 11 Jun 2015 11:29:09 -0400 Subject: [PATCH 10/12] add user authentication, logging in and out --- .../app/controllers/application_controller.rb | 1 + source/app/controllers/sessions_controller.rb | 21 ++++++++++ source/app/controllers/urls_controller.rb | 37 ++++++++++++++++-- source/app/controllers/users_controller.rb | 1 + source/app/helpers/sessions_helper.rb | 20 ++++++++++ source/app/views/layouts/application.html.erb | 9 ++++- source/app/views/sessions/new.html.erb | 18 +++++++++ source/app/views/urls/.index.html.erb.swp | Bin 12288 -> 0 bytes source/app/views/urls/edit.html.erb | 16 ++++++-- source/app/views/urls/index.html.erb | 1 + source/config/routes.rb | 10 ++++- .../controllers/sessions_controller_spec.rb | 12 ++++++ source/spec/helpers/sessions_helper_spec.rb | 15 +++++++ .../spec/views/sessions/new.html.erb_spec.rb | 5 +++ 14 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 source/app/views/sessions/new.html.erb delete mode 100644 source/app/views/urls/.index.html.erb.swp create mode 100644 source/spec/controllers/sessions_controller_spec.rb create mode 100644 source/spec/helpers/sessions_helper_spec.rb create mode 100644 source/spec/views/sessions/new.html.erb_spec.rb diff --git a/source/app/controllers/application_controller.rb b/source/app/controllers/application_controller.rb index d83690e..d8b3d09 100644 --- a/source/app/controllers/application_controller.rb +++ b/source/app/controllers/application_controller.rb @@ -2,4 +2,5 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception + include SessionsHelper end diff --git a/source/app/controllers/sessions_controller.rb b/source/app/controllers/sessions_controller.rb index 16d11b5..e00b760 100644 --- a/source/app/controllers/sessions_controller.rb +++ b/source/app/controllers/sessions_controller.rb @@ -1,2 +1,23 @@ class SessionsController < ApplicationController + + def new + end + + def create + user = User.find_by(email: params[:session][:email].downcase) + if user && user.authenticate(params[:session][:password]) + log_in user + flash[:success] = "You are now logged in" + redirect_to urls_path + else + flash.now[:danger] = "User could not be authenticated" + render 'new' + end + end + + def destroy + log_out + flash[:success] = "You are logged out" + redirect_to root_url + end end diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index d164757..113c586 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -3,6 +3,8 @@ class UrlsController < ApplicationController before_action :get_url, only: [:show, :destroy] + before_action :logged_in_user, only: [:edit, :update, :create] + before_action :correct_user, only: [:edit, :update, :destroy] def index @urls = Url.all @@ -23,6 +25,20 @@ def new @url = Url.new end + def edit + @url = get_url + end + + def update + @url = get_url + if @url.update(url_params) + flash[:success] = "Url successfully updated" + redirect_to urls_path + else + render 'edit' + end + end + def destroy @url.destroy redirect_to_index @@ -47,7 +63,22 @@ def get_url @url = Url.find(params[:id]) end - def url_params - params.require(:url).permit(:address) - end + private + + def url_params + params.require(:url).permit(:address) + end + + def logged_in_user + unless logged_in? + flash[:danger] = "Please log in" + redirect_to login_url + end + end + + def correct_user + # TODO Make this reference the user attached to the Url + @user = User.find(params[:id]) + redirect_to(root_url) unless current_user?(@user) + end end diff --git a/source/app/controllers/users_controller.rb b/source/app/controllers/users_controller.rb index 628c343..ca6780b 100644 --- a/source/app/controllers/users_controller.rb +++ b/source/app/controllers/users_controller.rb @@ -7,6 +7,7 @@ def new def create @user = User.new(user_params) if @user.save + log_in @user flash[:success] = "User successfully created" redirect_to urls_path else diff --git a/source/app/helpers/sessions_helper.rb b/source/app/helpers/sessions_helper.rb index 309f8b2..88f4944 100644 --- a/source/app/helpers/sessions_helper.rb +++ b/source/app/helpers/sessions_helper.rb @@ -1,2 +1,22 @@ module SessionsHelper + def log_in(user) + session[:user_id] = user.id + end + + def current_user + @current_user ||= User.find_by(id: session[:user_id]) + end + + def logged_in? + !current_user.nil? + end + + def log_out + session.delete(:user_id) + @current_user = nil + end + + def current_user?(user) + user == current_user + end end diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index e5a2805..ab00d11 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -7,6 +7,14 @@ <%= csrf_meta_tags %> +
+ <% if logged_in? %> +

<%= link_to "Log out", logout_path, method: :delete %>

+ <% else %> +

<%= link_to "Log in", login_path %>

+ <% end %> + +
<% flash.each do |message_type, message| %>
<%= message %>
@@ -14,7 +22,6 @@ <%= yield %> -<%= link_to "Sign up", signup_path %> <%= debug(params) if Rails.env.development? %> diff --git a/source/app/views/sessions/new.html.erb b/source/app/views/sessions/new.html.erb new file mode 100644 index 0000000..8bc7a43 --- /dev/null +++ b/source/app/views/sessions/new.html.erb @@ -0,0 +1,18 @@ +

Log in

+ +
+
+ <%= form_for(:session, url: login_path) do |f| %> + + <%= f.label :email %> + <%= f.text_field :email, class: 'form_control' %> + + <%= f.label :password %> + <%= f.password_field :password, class: 'form_control' %> + + <%= f.submit "Log in", class: "btn btn-primary" %> + <% end %> + +

<%= link_to "New User?", signup_path %>

+
+
diff --git a/source/app/views/urls/.index.html.erb.swp b/source/app/views/urls/.index.html.erb.swp deleted file mode 100644 index c87caca212a2562aad1f50b317e9008a8ba31fe7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2J#P~+7{^^Uh5`Z>#PX1;3P>fFl7T9^gqOAhsD+^~f~h#M%bjvLpU%FfDFwa* zGwjT4dOf{$uodfp4T?OmL7XbRU5i{lsp-5kHU)RG0X8tsK;bqo z&rOQPmD##~Jyp3tXHKt;i{w5wzy{a=8(;%$fDNz#Hoyk{Qv)uW5KpnUW99zNm-WP< zx@>aA2G{@_U;}J`4X^<=zy{a=8(;%$fDQbE2BZ?=_M{N+fdBu0|M&lwlR|t3pTGz3 z2D}0K#3xwLGcLP^t$TxJA8@Nf*&{TZpie`_I71 zPNLg_2#+13hW-(aY0|0kfxd-y)~3}+=b9u)4fz|{7?K@?$D4HBch+pYqp8)R`u^x& z<_a8A?@jAxcB=i;nisTnxfx>3m~Mvp+C@e+si}0Lot_~joov!0>Y8*j&ihTO-oTQE zrXXA7`dXD9BQZ9kj>xg7Vuu78)q$0ZNO$SaLsud*7_IHMv6!ePmCCiXhhoD0ox{n< zmX_U!l%ZV=+C?Editing url +

Update link

-<%= render 'form' %> +
+
+ <%= form_for(@url) do |f| %> -<%= link_to 'Show', @url %> | -<%= link_to 'Back', urls_path %> + <%= f.label :address %> + <%= f.text_field :address, class: 'form-control' %> + + <%= f.submit "Save changes", class: "btn btn-primary" %> + <% end %> + +
+
diff --git a/source/app/views/urls/index.html.erb b/source/app/views/urls/index.html.erb index 67bb190..b243420 100644 --- a/source/app/views/urls/index.html.erb +++ b/source/app/views/urls/index.html.erb @@ -13,6 +13,7 @@ <%= link_to root_url + url.unique_key, url.unique_key %> <%= url.address %> <%= url.click_count %> + <%= link_to 'Edit', edit_url_path(url) %> <%= link_to 'Destroy', url, method: :delete, data: { confirm: 'Are you sure?' } %> <% end %> diff --git a/source/config/routes.rb b/source/config/routes.rb index 3959150..b7217fd 100644 --- a/source/config/routes.rb +++ b/source/config/routes.rb @@ -1,14 +1,20 @@ Rails.application.routes.draw do + get 'sessions/new' + get 'users/new' root 'urls#index' get '/urls', to: 'urls#index' get '/signup', to: 'users#new' + get '/login', to: 'sessions#new' + post '/login', to: 'sessions#create' + delete '/logout', to: "sessions#destroy" + get '/:unique_key', to: 'urls#expand_link' - resources :urls, except: [:show, :edit, :update, :index] - resources :users + resources :urls, except: [:index] + resources :users, except: [:show, :edit, :update, :index, :destroy] # 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/spec/controllers/sessions_controller_spec.rb b/source/spec/controllers/sessions_controller_spec.rb new file mode 100644 index 0000000..f524aa5 --- /dev/null +++ b/source/spec/controllers/sessions_controller_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +RSpec.describe SessionsController, type: :controller do + + describe "GET #new" do + it "returns http success" do + get :new + expect(response).to have_http_status(:success) + end + end + +end diff --git a/source/spec/helpers/sessions_helper_spec.rb b/source/spec/helpers/sessions_helper_spec.rb new file mode 100644 index 0000000..9484198 --- /dev/null +++ b/source/spec/helpers/sessions_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the SessionsHelper. For example: +# +# describe SessionsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe SessionsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/source/spec/views/sessions/new.html.erb_spec.rb b/source/spec/views/sessions/new.html.erb_spec.rb new file mode 100644 index 0000000..6de37da --- /dev/null +++ b/source/spec/views/sessions/new.html.erb_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe "sessions/new.html.erb", type: :view do + pending "add some examples to (or delete) #{__FILE__}" +end From ab7f31ac351895cccde7381a0acd0ef08ea34cb0 Mon Sep 17 00:00:00 2001 From: Kaleb Davis Date: Thu, 11 Jun 2015 12:48:00 -0400 Subject: [PATCH 11/12] add foreign key to connect urls to user --- .../migrate/20150611153619_add_foreign_key_to_urls.rb | 5 +++++ source/db/schema.rb | 11 +++-------- 2 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 source/db/migrate/20150611153619_add_foreign_key_to_urls.rb diff --git a/source/db/migrate/20150611153619_add_foreign_key_to_urls.rb b/source/db/migrate/20150611153619_add_foreign_key_to_urls.rb new file mode 100644 index 0000000..fc47274 --- /dev/null +++ b/source/db/migrate/20150611153619_add_foreign_key_to_urls.rb @@ -0,0 +1,5 @@ +class AddForeignKeyToUrls < ActiveRecord::Migration + def change + add_column :urls, :user_id, :foreign_key + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index 464b060..58f64a8 100644 --- a/source/db/schema.rb +++ b/source/db/schema.rb @@ -11,15 +11,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150611133240) do +ActiveRecord::Schema.define(version: 20150611153619) do - create_table "urls", force: true do |t| - t.string "address" - t.string "unique_key" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "click_count", default: 0 - end +# Could not dump table "urls" because of following NoMethodError +# undefined method `[]' for nil:NilClass create_table "users", force: true do |t| t.string "email" From b81a66649400c9e929643458f756d7b63608b2f7 Mon Sep 17 00:00:00 2001 From: Bryon Wilkins Date: Thu, 11 Jun 2015 13:47:21 -0400 Subject: [PATCH 12/12] added admin and restriciton functionality --- source/Gemfile.lock | 2 +- source/app/controllers/urls_controller.rb | 8 ++-- source/app/helpers/sessions_helper.rb | 4 ++ source/app/models/url.rb | 42 +++++++++---------- source/app/views/layouts/application.html.erb | 4 +- source/db/migrate/20150611173030_addadmin.rb | 5 +++ source/db/schema.rb | 3 +- 7 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 source/db/migrate/20150611173030_addadmin.rb diff --git a/source/Gemfile.lock b/source/Gemfile.lock index e5dd0c6..1f37a5d 100644 --- a/source/Gemfile.lock +++ b/source/Gemfile.lock @@ -153,4 +153,4 @@ DEPENDENCIES uglifier (>= 1.3.0) BUNDLED WITH - 1.10.2 + 1.10.3 diff --git a/source/app/controllers/urls_controller.rb b/source/app/controllers/urls_controller.rb index 113c586..0b2c104 100644 --- a/source/app/controllers/urls_controller.rb +++ b/source/app/controllers/urls_controller.rb @@ -3,7 +3,7 @@ class UrlsController < ApplicationController before_action :get_url, only: [:show, :destroy] - before_action :logged_in_user, only: [:edit, :update, :create] + before_action :logged_in_user, only: [:edit, :update, :create, :destroy] before_action :correct_user, only: [:edit, :update, :destroy] def index @@ -12,6 +12,7 @@ def index def create @url = Url.new(url_params) + @url.user_id = current_user if @url.save flash[:success] = 'Url was successfully created' redirect_to urls_path @@ -77,8 +78,7 @@ def logged_in_user end def correct_user - # TODO Make this reference the user attached to the Url - @user = User.find(params[:id]) - redirect_to(root_url) unless current_user?(@user) + user = User.find(get_url.user_id) + redirect_to(root_url) unless current_user?(user) || admin? end end diff --git a/source/app/helpers/sessions_helper.rb b/source/app/helpers/sessions_helper.rb index 88f4944..e0f78ca 100644 --- a/source/app/helpers/sessions_helper.rb +++ b/source/app/helpers/sessions_helper.rb @@ -19,4 +19,8 @@ def log_out def current_user?(user) user == current_user end + + def admin? + current_user.admin + end end diff --git a/source/app/models/url.rb b/source/app/models/url.rb index 26ce73d..23929c5 100644 --- a/source/app/models/url.rb +++ b/source/app/models/url.rb @@ -8,35 +8,35 @@ class Url < ActiveRecord::Base # validates :address, :format => URI::regexp(%w(http https)) validates_uniqueness_of :unique_key - # IN PROGRESS - def validate_url - if self.address.match(/^https?:\/\//).nil? - errors.add(:address, "needs to be a valid url") - else - if self.address.match(URI::regexp(%w(http https))).nil? + private + + def validate_url + if self.address.match(/^https?:\/\//).nil? errors.add(:address, "needs to be a valid url") - end + else + if self.address.match(URI::regexp(%w(http https))).nil? + errors.add(:address, "needs to be a valid url") + end - begin - response = send_http_request(self.address) - if response.status.to_i >= 400 + begin + response = send_http_request(self.address) + if response.status.to_i >= 400 + errors.add(:address, "needs to be a valid url") + end + rescue Faraday::ConnectionFailed errors.add(:address, "needs to be a valid url") end - rescue Faraday::ConnectionFailed - errors.add(:address, "needs to be a valid url") end end - end - def shorten_address - if self.unique_key.nil? - self.unique_key = 8.times.map { [*'0'..'9', *'a'..'z'].sample }.join + def shorten_address + if self.unique_key.nil? + self.unique_key = 8.times.map { [*'0'..'9', *'a'..'z'].sample }.join + end end - end - private - def send_http_request url - Faraday.head url - end + def send_http_request url + Faraday.head url + end end diff --git a/source/app/views/layouts/application.html.erb b/source/app/views/layouts/application.html.erb index ab00d11..153ce37 100644 --- a/source/app/views/layouts/application.html.erb +++ b/source/app/views/layouts/application.html.erb @@ -10,10 +10,12 @@
<% if logged_in? %>

<%= link_to "Log out", logout_path, method: :delete %>

+ <% if admin? %> +

YOU'RE AN ADMIN!

+ <% end %> <% else %>

<%= link_to "Log in", login_path %>

<% end %> -
<% flash.each do |message_type, message| %> diff --git a/source/db/migrate/20150611173030_addadmin.rb b/source/db/migrate/20150611173030_addadmin.rb new file mode 100644 index 0000000..db45695 --- /dev/null +++ b/source/db/migrate/20150611173030_addadmin.rb @@ -0,0 +1,5 @@ +class Addadmin < ActiveRecord::Migration + def change + add_column :users, :admin, :boolean, default: false + end +end diff --git a/source/db/schema.rb b/source/db/schema.rb index 58f64a8..58b0bfc 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: 20150611153619) do +ActiveRecord::Schema.define(version: 20150611173030) do # Could not dump table "urls" because of following NoMethodError # undefined method `[]' for nil:NilClass @@ -21,6 +21,7 @@ t.datetime "created_at" t.datetime "updated_at" t.string "password_digest" + t.boolean "admin", default: false end add_index "users", ["email"], name: "index_users_on_email", unique: true