友好URL按名称而不是ID路由的问题

时间:2009-10-19 18:29:38

标签: ruby-on-rails ruby routing routes url-routing

我的代码中有一条如下所示的路径:

map.app 'applications/:title_header', :controller => 'apps', :action => 'show'

我还将控制器中的show方法更改为:

@app = App.find_by_title_header(params[:title_header])

如果我输入applications/title,事情就可以了。如果我输入applications/1(有效身份证),则会失败(如预期的那样)

但是,当我尝试使用友好的网址助手时,在这种情况下app_path(@app)生成的网址类似于applications/1。我能让它发挥作用的唯一方法就是投入app_path(@app.title_header)。似乎它“只知道”ID是从app对象中传出的内容,它应该“只知道”它现在应该默认传递名称。我需要改变什么?

4 个答案:

答案 0 :(得分:3)

最简单,最轻的解决方案就是使用to_param:

class Application < ActiveRecord::Base

  def to_param
    title_header.parameterize
  end

end

String实例方法parameterize将确保字符串适合URL。然后,在您的控制器中,您只需更新所有find即可使用find_by_title_header而非find

确保title_header是唯一的!

答案 1 :(得分:0)

我认为你需要在App上定义一个to_param方法,但请查看acts_as_friendly_param,它为你做了更多:http://chrisfarms.googlecode.com/svn/rails/plugins/acts_as_friendly_param/

答案 2 :(得分:0)

实际上我最终做的并不是触及to_param。我的其他页面需要to_param成为ID,而不是固定链接,这太难看了。

我最后只是将@app.permalink传递给了网址方法,而不是触及to_param,但是知道这一点仍然有用。

答案 3 :(得分:-1)

听起来很对。 Rails不假设它在命名路由中遇到的符号是对象上的方法。

解决此问题的最佳方法是向application_helper.rb添加一个自定义帮助程序,该帮助程序将获取您要使用的语法并将其传递给更基本的url版本。

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