fullstackplus
fullstackplus

Reputation: 1071

Finding records by a slug instead of id in Rails

I am trying to create semantic URLs for a simple miniblog app, but am stuck with to_param and retrieving the records. This is the Post model:

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

Now, every time I'm linking to posts with link_to @post.title, @post I get this error:

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

The show action looks like this:

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

When I do the above it tries to find the post with the slug as the id, but the slug is not the id so I get an error. When I use the standard find(params[:id]) it cannot find the record because to_param is overridden.

What am I missing?

Thanks.

Upvotes: 2

Views: 2528

Answers (1)

Hesham
Hesham

Reputation: 2347

Change after_create :create_slug to before_create :create_slug.

If you want to use after_create, you have to save the object after you set the slug.

Upvotes: 3

Related Questions