在Rails中通过slug而不是id查找记录

时间:2014-09-23 14:41:02

标签: ruby-on-rails url activerecord model-view-controller routing

我正在尝试为一个简单的迷你日志应用创建语义URL,但我坚持使用to_param并检索记录。这是Post模型:

class Post < ActiveRecord::Base
  after_create :create_slug

  validates :title, :body, :presence => true
  validates :title, length: { maximum: 250 }
  validates :body, length:  { maximum: 5000 }

  def to_param
    slug
  end

  private
  def create_slug
    self.slug = slugify
  end

  def slugify
    [year_month_day, title.parameterize].join("-")
  end

  def year_month_day
    [created_at.year, created_at.strftime("%m"), created_at.strftime("%d")].join
  end
end

现在,每次我使用link_to @post.title, @post链接帖子时都会收到此错误:

No route matches {:action=>"show", :controller=>"posts", :id=>nil} missing required keys: [:id]

show操作如下所示:

def show
  @post = Post.find_by_slug(params[:id])
end

当我执行上述操作时,它会尝试使用slug作为id找到帖子,但是slug不是id,所以我收到错误。当我使用标准find(params[:id])时,它无法找到记录,因为to_param被覆盖。

我错过了什么?

感谢。

1 个答案:

答案 0 :(得分:3)

after_create :create_slug更改为before_create :create_slug

如果你想使用after_create,你必须在设置slug后保存对象。