Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DONE. :D #39

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions source/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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]
11 changes: 11 additions & 0 deletions source/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ 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)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
Expand All @@ -50,9 +52,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)
Expand Down Expand Up @@ -125,9 +131,11 @@ PLATFORMS
ruby

DEPENDENCIES
bcrypt (~> 3.1.7)
coffee-rails (~> 4.0.0)
jbuilder (~> 2.0)
jquery-rails
pry
rails (= 4.1.6)
rspec-rails
sass-rails (~> 4.0.3)
Expand All @@ -136,3 +144,6 @@ DEPENDENCIES
sqlite3
turbolinks
uglifier (>= 1.3.0)

BUNDLED WITH
1.16.1
4 changes: 4 additions & 0 deletions source/app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@
*= require_tree .
*= require_self
*/

div#flash_error {
color: red;
}
14 changes: 14 additions & 0 deletions source/app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions source/app/controllers/urls_controller.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,38 @@
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.find_or_initialize_by(url_params)
if @url.save
redirect_to urls_path
else
flash[:error] = @url.errors.full_messages
redirect_to new_url_path(@url)
end
end

def show
@url.click_count += 1
@url.save

redirect_to "#{@url.long_url}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string interpolation isn't needed here. redirect_to @url.long_url should do the trick.

end

private

def set_url
@url = Url.find_by(short_url: params[:short_url])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this method is only invoked for one controller action, I'd suggest inlining it there.

end

def url_params
params.require(:url).permit(:long_url, :short_url)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We permit setting the short_url here, but there isn't an input in the form for it, and it will be overwritten in the model. I think short_url should be removed here.

end
end
29 changes: 29 additions & 0 deletions source/app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -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
31 changes: 31 additions & 0 deletions source/app/models/url.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class Url < ActiveRecord::Base
belongs_to :user

validates :long_url, presence: true
validates :short_url, uniqueness: true

validate :uri_properly_formatted

before_create :create_short_url

def create_short_url
begin
short_url = SecureRandom.hex(4)
end while Url.where(short_url: short_url).exists?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure Url.exists?(short_url: short_url) works here too.


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?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you had a bug here. Instead, I just learned that URI::HTTPS is a subclass of URI::HTTP. 👍

rescue URI::InvalidURIError
false
end

def uri_properly_formatted
unless self.compliant?
errors.add(:long_url, "must include 'http://' or 'https://'")
end
end
end
7 changes: 7 additions & 0 deletions source/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class User < ActiveRecord::Base
has_secure_password

validates :username, uniqueness: true

has_many :urls
end
5 changes: 5 additions & 0 deletions source/app/views/layouts/_error_messages.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<% if flash[:error] %>
<%= content_tag :div, flash[:error], id: "flash_error" do %>
<%= flash[:error].join(", ") %>
<% end %>
<% end %>
10 changes: 10 additions & 0 deletions source/app/views/layouts/_navigation.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<% if session[:user_id] %>
<ul>
<li><%= link_to "Main", urls_path %></li>
<li><%= link_to "Profile", user_path(session[:user_id]) %></li>
<li><%= link_to "Logout", log_out_path %></li>
</ul>

<% else %>
<%= link_to "Login", log_in_path %> or <%= link_to "Signup", sign_up_path %>
<% end %>
2 changes: 2 additions & 0 deletions source/app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
</head>
<body>

<%= render "/layouts/navigation" %>

<%= yield %>

</body>
Expand Down
5 changes: 5 additions & 0 deletions source/app/views/sessions/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= form_for :user do |f| %>
Username: <%= f.text_field :username %>
Password: <%= f.password_field :password %>
<%= f.submit "Login" %>
<% end %>
10 changes: 10 additions & 0 deletions source/app/views/urls/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%= link_to "Create a new short link", new_url_path %>

<ul>
<% @urls.each do |url| %>
<li>
<%= link_to "#{url.long_url}", url.long_url %><br>
<%= link_to "#{short_url_url(url.short_url)}", short_url_path(url.short_url) %>
</li>
<% end %>
</ul>
6 changes: 6 additions & 0 deletions source/app/views/urls/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= render '/layouts/error_messages' %>

<%= form_for @url do |f| %>
<%= f.text_field :long_url, placeholder: "Paste url text here" %>
<%= f.submit "Shorten" %>
<% end %>
7 changes: 7 additions & 0 deletions source/app/views/users/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1>Sign up!</h1>
<%= 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 %>
9 changes: 9 additions & 0 deletions source/app/views/users/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Username: <%= @user.username %>
<ul>
<% @user.urls.each do |url| %>
<li>
Original url: <%= link_to "#{url.long_url}", url.long_url %><br>
Short url: <%= link_to "#{short_url_url(url.short_url)}", short_url_path(url.short_url) %>
</li>
<% end %>
</ul>
59 changes: 7 additions & 52 deletions source/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,56 +1,11 @@
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".
resources :urls, only: [:index, :new, :create]
resources :users, only: [:create, :show]

# You can have the root of your site routed with "root"
# root 'welcome#index'
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: "sign_up"

# 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
get "/:short_url", to: "urls#show", as: "short_url"
end
10 changes: 10 additions & 0 deletions source/db/migrate/20180514210613_create_urls.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions source/db/migrate/20180515133521_add_click_count_to_urls.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddClickCountToUrls < ActiveRecord::Migration
def change
add_column :urls, :click_count, :integer, default: 0
end
end
10 changes: 10 additions & 0 deletions source/db/migrate/20180515172345_create_users.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions source/db/migrate/20180515194957_add_user_id_to_urls.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddUserIdToUrls < ActiveRecord::Migration
def change
add_column :urls, :user_id, :integer
end
end
32 changes: 32 additions & 0 deletions source/db/schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 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: 20180515194957) 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
t.integer "user_id"
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
5 changes: 5 additions & 0 deletions source/spec/models/url_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe Url, :type => :model do
pending "add some examples to (or delete) #{__FILE__}"
end
Loading