Permalink
Browse files

Add slugs to posts

Change: blog.edwardloveall.com/posts/1
To:     blog.edwardloveall.com/hello-world

This required me to use the root_url instead of posts_url because
posts_url(subdomain: 'blog') visits blog.edwardloveall.com/posts which
thinks it's looking for a post with the slug of "posts".
  • Loading branch information...
edwardloveall committed Aug 22, 2016
1 parent c44d335 commit 55da8b4d1c862314ea73611f33b9edae33f3a690
@@ -39,7 +39,7 @@ def destroy
private
def post_params
- params.require(:post).permit(:title, :body)
+ params.require(:post).permit(:title, :body, :slug)
end
def find_post
@@ -7,6 +7,6 @@ def index
end
def show
- @post = Post.find(params[:id])
+ @post = Post.find_by(slug: params[:slug])
end
end
View
@@ -1,6 +1,7 @@
class Post < ActiveRecord::Base
validates :body, presence: true
validates :title, presence: true
+ validates :slug, presence: true, uniqueness: true
scope :newest_first, lambda { order(created_at: :desc) }
end
@@ -3,6 +3,7 @@
<div class="form-inputs">
<%= form.input :title %>
+ <%= form.input :slug %>
<%= form.input :body %>
</div>
@@ -1,5 +1,5 @@
<article class="post">
- <h2><%= link_to post.title, post %></h2>
+ <h2><%= link_to post.title, post_path(post.slug) %></h2>
<aside class="meta">
<%= link_to post do %>
Posted
View
@@ -1,7 +1,8 @@
Rails.application.routes.draw do
constraints(subdomain: /blog.*/) do
get '/', to: 'posts#index'
- resources :posts, only: [:index, :show]
+ get '/:slug', to: 'posts#show', as: :post
+ resources :posts, only: [:index]
end
root to: 'projects#index'
@@ -0,0 +1,5 @@
+class AddSlugToPosts < ActiveRecord::Migration
+ def change
+ add_column :posts, :slug, :string, unique: true, index: true
+ end
+end
View
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160817014307) do
+ActiveRecord::Schema.define(version: 20160822180105) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -21,6 +21,7 @@
t.datetime "updated_at", null: false
t.string "title"
t.text "body"
+ t.string "slug"
end
create_table "projects", force: :cascade do |t|
@@ -42,7 +42,7 @@
it 'assigns the requested post as @post' do
post = create(:post)
- get :show, id: post.id
+ get :show, slug: post.slug
expect(assigns(:post)).to eq(post)
end
View
@@ -2,5 +2,6 @@
factory :post do
title 'A Scary Story'
body 'It was a dark and stormy night...'
+ slug { |n| "a-scary-story-#{n}" }
end
end
@@ -23,7 +23,7 @@
click_on 'Add post'
fill_form_and_submit(:post, :new, attributes)
- visit posts_url(subdomain: :blog)
+ visit root_url(subdomain: :blog)
expect(page).to have_content(attributes[:title])
end
@@ -4,16 +4,28 @@
scenario 'and sees pagination links' do
create_list(:post, 11)
- visit posts_url(subdomain: 'blog')
+ visit root_url(subdomain: 'blog')
expect(page).to have_link('Older', posts_url(subdomain: 'blog', page: 2))
end
scenario 'and sees pagination links' do
create_list(:post, 11)
- visit posts_url(subdomain: 'blog', page: 2)
+ visit root_url(subdomain: 'blog', page: 2)
expect(page).to have_link('Newer', posts_url(subdomain: 'blog', page: 1))
end
+
+ scenario 'and visits a specific post' do
+ post = create(:post)
+
+ visit root_url(subdomain: 'blog')
+ click_on(post.title)
+
+ expect(current_url).to eq(post_url(subdomain: 'blog', slug: post.slug))
+ within('article h2') do
+ expect(page).to have_content(post.title)
+ end
+ end
end
View
@@ -4,6 +4,8 @@
describe 'validations' do
it { should validate_presence_of(:body) }
it { should validate_presence_of(:title) }
+ it { should validate_presence_of(:slug) }
+ it { should validate_uniqueness_of(:slug) }
end
describe '.newest_first' do

0 comments on commit 55da8b4

Please sign in to comment.