Reputation: 861
I develop my Rails app on the Cloud9.
What I'd like to do is to set a part of title to the URL such as stackoverflow.
(e.g. example.com/part-of-tile-here
)
Although I found the similar questions, I don't understand what I should do because some of them are old posts, links in the answer are not found. (e.g. Adding title to rails route)
I will not use Gem as yet.
It would be appreciated if you could give me any hint.
Upvotes: 0
Views: 1039
Reputation: 1968
Generally, Ho Man is right but there are a few caveats to the proposed solution.
First of all, you should override the to_param
method as well so it actually uses the slug:
# app/models/page.rb
def to_param
slug
end
# ... which allows you to do this in views/controllers:
page_path(@page)
# instead of
page_path(@page.slug)
Second, you should use find_by!(slug: params[:id])
to 1) be up to date (find_by_xxx
was deprecated in Rails 4.0 and removed from Rails 4.1) and 2) to replicate the behavior of find
and raise an ActiveRecord::RecordNotFound
error in case no post can be found for the given slug.
Third, I suggest to always keep the slug up to date and include the ID like so:
# app/models/page.rb
before_validation :set_slug
def to_param
"#{id}-#{slug}"
end
private
def set_slug
self.slug = title.parameterize
end
# ... which allows you to use the regular ActiveRecord find again because it just looks at the ID in this case:
@post = Post.find(params[:id]) # even if params[:id] is something like 1-an-example-post
If you care about search engine results, you should then also include the canonical URL in the <head>
section and/or redirect with a 301 status in the controller to avoid duplicate content which search engines generally don't like:
# in the view
<%= tag(:link, rel: :canonical, href: page_url(@page)) %>
# and/or in the controller:
redirect_to(post_url(@post), status: 301) and return unless params[:id] == @post.to_param
Hope that helps.
Upvotes: 4
Reputation: 2345
Have a look at this Railscast which is roughly what you want.
tl;dr
You'll want to save a slug
which is a parameterized title, delimited by -
when you save the page. (In a before_validation
or before_save
)
For example, "Random Title Of Page" will get random-title-of-page
generated as it's slug.
before_validation :generate_slug
def generate_slug
self.slug ||= title.parameterize
end
In the page controller, you'll need to enable searching by slug
.
def show
@page = Page.find_by_slug(params[:id])
end
Upvotes: 2