views:

355

answers:

4

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?

A: 

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
EmFi
A: 

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%5Fas%5Ffriendly%5Fparam/

Brad G.
+3  A: 

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 finds to use find_by_title_header instead of just find.

Make sure you're title_headers will be unique!

Ben
Thanks I ended up doing something like this...
Stacia
A: 

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.

Stacia