Article slugs #155

Merged
merged 4 commits into from Aug 18, 2013
@@ -47,7 +47,7 @@ def destroy
private
def find_article
- @article = Article.find(params[:id])
+ @article = Article[params[:id]]
end
end
end
@@ -1,5 +1,6 @@
class ArticlesController < ApplicationController
before_filter :find_article, :only => [:show, :edit, :update, :share]
+ before_filter :redirect_to_slug, :only => [:show]
before_filter :create_visit, :only => [:show]
skip_before_filter :authenticate, :only => [:shared, :samples]
@@ -80,11 +81,7 @@ def random
private
def find_article
- if params[:volume] && params[:issue]
- @article = Article.find_by_issue_number("#{params[:volume]}.#{params[:issue]}")
- else
- @article = Article.find_by_id(params[:id])
- end
+ @article = Article[params[:id]]
render_http_error(404) unless @article
end
@@ -108,4 +105,9 @@ def create_visit
end
end
+ def redirect_to_slug
+ return unless @article.slug.present?
+
+ redirect_to article_path(@article.slug) unless params[:id] == @article.slug
+ end
end
View
@@ -3,7 +3,8 @@ class Article < ActiveRecord::Base
belongs_to :volume
belongs_to :collection
- validates_presence_of :issue_number
+ validates_presence_of :issue_number
+ validates_uniqueness_of :slug, :allow_blank => true
def self.in_volume(number)
includes(:volume)
@@ -18,6 +19,18 @@ def self.drafts
where(:status => "draft")
end
+ def self.[](key)
+ find_by_slug(key) || find_by_id(key)
+ end
+
+ def to_param
+ if slug.present?
+ slug
+ else
+ id.to_s
+ end
+ end
+
def full_subject
"Issue #{issue_number}: #{subject}"
end
@@ -5,6 +5,10 @@
%br
= f.text_field :subject
%p
+ = f.label :slug
+ %br
+ = f.text_field :slug
+%p
= f.label :published_time
= f.date_select :published_time
%p
@@ -0,0 +1,5 @@
+class AddSlugToArticles < ActiveRecord::Migration
+ def change
+ add_column :articles, :slug, :string
+ end
+end
View
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20130215174537) do
+ActiveRecord::Schema.define(:version => 20130816174433) do
create_table "announcements", :force => true do |t|
t.text "title"
@@ -43,6 +43,7 @@
t.text "issue_number"
t.integer "volume_id"
t.integer "collection_id"
+ t.string "slug"
end
create_table "authorization_links", :force => true do |t|
@@ -0,0 +1,35 @@
+require_relative "../test_helper"
+
+class ArticleRoutingTest < ActionDispatch::IntegrationTest
+ setup do
+ @article = FactoryGirl.create(:article, :slug => "awesome-article")
+ simulated_user { register Support::SimulatedUser.default }
+ end
+
+ test "by slug" do
+ visit "/articles/awesome-article"
+
+ assert_content @article.subject
+ end
+
+ test "by id" do
+ id = @article.id
+ visit "/articles/#{id}"
+
+ assert_content @article.subject
+
+ assert_current_path "/articles/awesome-article"
+ end
+
+ test "with invalid slug" do
+ visit "/articles/i-do-no-exist"
+
+ assert_equal 404, page.status_code
+ end
+
+ test "with invalid id" do
+ visit "/articles/99999"
+
+ assert_equal 404, page.status_code
+ end
+end
@@ -0,0 +1,27 @@
+require_relative '../test_helper'
+
+class EditArticleTest < ActionDispatch::IntegrationTest
+ setup do
+ simulated_user { register Support::SimulatedUser.default }
+ @article = FactoryGirl.create(:article, :slug => "awesome-article")
+ User.first.update_attribute(:admin, true)
+ end
+
+ test "can edit articles with slugs" do
+ visit edit_admin_article_path(@article.slug)
+
+ click_button "Update Article"
+
+ assert_current_path article_path(@article)
+ end
+
+ test "can edit articles without slugs" do
+ @article.update_attribute(:slug, nil)
+
+ visit edit_admin_article_path(@article.id)
+
+ click_button "Update Article"
+
+ assert_current_path article_path(@article)
+ end
+end