Reputation: 1167
Let's say I have a relatively basic CRUD application for editing music albums. In the database I have:
id | album_name | artist | navigation
1 Lets Talk Lagwagon lets-talk
However, instead of albums/1
returning my Show
page, I want the page to be accessible by the albums/lets-talk
route.
So in my controller I have:
def show
@album = Album.find_by_navigation(params[:id])
end
And in my index view I have:
<%= link_to 'Show', :controller => "albums", :action => "show", :id => album.navigation %>
This successfully performs its function, however, the Ruby API says my link_to method is old and archaic without listing an alternative, so I suspect I'm going about this the wrong way.
Upvotes: 4
Views: 6077
Reputation: 791
If you want to display URL in browser as app/albums/lets-talk
but POST params as album_id => 1
, for shopping cart addition etc.
In your album model:
# PRODUCT MODEL
before_create do
self.navigation = album_name.downcase.gsub(" ", "-")
end
def to_param
[id, album_name.parameterize].join("-")
end
Now you can
@album = Album.find_by_navigation(params[:id])
and
album = Album.find(params[:album_id])
Upvotes: 1
Reputation: 4705
Define your to_param in the model:
class album
def to_param
"#{id}-#{album-name.parameterize}"
end
end
Now you can use
<%= link_to album.album_name, album %>
to create the link to the seo path
Then in your controller:
Album.find(params[:id])
will call to_i
-> so you get the Topic.find(2133)
or whatever.
This will result in urls of the form: "/album/2-dark-side-of-the-moon" which although not exactly what was asked for has advantages - The id is used to find the album - which is unique, when the name might not be.
The parameterize method "Replaces special characters in a string so that it may be used as part of a ‘pretty’ URL" - http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize
Upvotes: 17
Reputation: 1124
It seems like you whant to override :id parameter to :name parameter. This case described in this article.
class User < ActiveRecord::Base
def to_param # overridden
name
end
end
user = User.find_by_name('Phusion')
link_to 'Show', user_path(user) # => <a href="/users/Phusion">Show</a>
Upvotes: 0