Reputation: 1793
I have a route in my code that looks like this:
map.app 'applications/:title_header', :controller => 'apps', :action => 'show'
I also changed my show method in the controller to be like this:
@app = App.find_by_title_header(params[:title_header])
If I type in applications/title
things work fine. If I type in applications/1
(valid Id) it fails (as expected)
However when I'm trying to use the friendly url helpers, in this case app_path(@app)
the URLs that are generated look like applications/1
. The only way I can get it to work is by putting in app_path(@app.title_header)
. It seems like if it "just knows" that the ID is what's being passed out of the app object that it should "just know" that it should by default pass the name instead now. What do I need to change?
Upvotes: 0
Views: 1633
Reputation: 1793
Actually what I ended up doing was not touching to_param. It was getting too ugly with other pages I had that needed the to_param
to be an ID, not a permalink.
I ended up just passing the @app.permalink
to the URL methods instead of touching to_param
, but that one is still useful to know.
Upvotes: 0
Reputation: 8348
Easiest, lightest solution is to just use to_param:
class Application < ActiveRecord::Base
def to_param
title_header.parameterize
end
end
The String instance method parameterize
will ensure the string is URL appropriate. Then, in your controllers you will just have to update all find
s to use find_by_title_header
instead of just find
.
Make sure you're title_header
s will be unique!
Upvotes: 3
Reputation: 811
I think you need to define a to_param method on App, for one, but check out acts_as_friendly_param, which does that for you and more: http://chrisfarms.googlecode.com/svn/rails/plugins/acts_as_friendly_param/
Upvotes: 0
Reputation: 23450
Sounds about right. Rails doesn't assume that the symbols it encounters in a named route are methods on an object.
The best way around this is to add a custom helper to application_helper.rb, that creates takes the syntax you want to use and passes it on to a more basic version of url for.
def my_app_path(object, args)
if object.responds_to? :title_header
app_path(object.title_header, args)
else
raise "Cannot generate url from object, missing title_header"
end
end
Upvotes: 0