假设我有一条路线get "/:year/:month/:slug", :as => :post"
。为了使它工作,我已经在Post
类中添加了以下方法:
def to_param
slug
end
现在,如果我想使用post_path
路由助手,我必须向它传递 3 个参数,例如:post_path({ year: '2013', month: '07', slug: 'lorem-ipsum' })
,但由于我不喜欢每次都编写它,所以我添加了另一种方法:
def uri
{ year: self.published_at.strftime('%Y'), month: self.published_at.strftime('%m'), slug: self.slug }
end
它允许我用来post_path(@post.uri)
获取路径。但这仍然不是我想要的。我想要的是能够在那里传递一个对象,比如post_path(@post)
,这给了我以下错误:
ActionController::RoutingError: No route matches {:controller=>"posts", :action=>"show", :year=>#<Post id: nil, slug: "lorem-ipsum", title: nil, body: nil, published: nil, published_at: nil, created_at: nil, updated_at: nil>}
可以很容易地推断,Rails 真正做的事情是这样的:post_path({ year: @post })
这显然是错误的。然而,Rails 生成的默认路由(仅用:id
作参数)在将对象传递给它之后才起作用。Rails 在内部是如何做到的?它是否使用任何Post
需要重载的隐藏方法?(我已经尝试过to_s
, url_options
,id
等但没有奏效。)
长话短说
怎么做才能让 Rails{ year: ..., month: ..., slug: ...}
在传递@post
给post_path
(而不是 eg @post.special_method
)后看到散列?
编辑:
来自 routes.rb 文件的摘录:
scope ':year/:month', :constraints => { year: /\d{4}/, month: /\d{2}/ } do
scope ':slug', :constraints => { slug: /[a-z0-9-]+/ } do
get '/' => 'posts#show', :as => :post
put '/' => 'posts#update'
delete '/' => 'posts#destroy'
get '/edit' => 'posts#edit', :as => :edit_post
end
end
get 'posts' => 'posts#index', :as => :posts
post 'posts' => 'posts#create'
get 'posts/new' => 'posts#new', :as => :new_post
也许会有所帮助。