Paw*_*cki 9 ruby rest ruby-on-rails
给定以下资源定义:
map.resources :posts, :except => [:show]
map.post '/:year/:month/:slug, :controller => :posts, :action => :show
Run Code Online (Sandbox Code Playgroud)
我可以url_for使用以下语法为我工作:
<%= link_to @post.title, post_url(:year => '2010', :month => '02', :slug => 'test') %>
Run Code Online (Sandbox Code Playgroud)
但有没有办法让这项工作?
<%= link_to @post.title, @post %>
Run Code Online (Sandbox Code Playgroud)
目前它抛出此错误:
No route matches {:year=>#<Post id: 1, title: "test", (...)>, :controller=>"posts", :action=>"show"}
Run Code Online (Sandbox Code Playgroud)
显然它将@post对象传递给第一个路由参数(看起来像是一个Rails错误...).但我可以为我做这项工作吗?我要补充一点,搞乱default_url_options是一个死胡同.
仅在Rails 3.x中工作的解决方案是可以的,但我不想使用任何插件.
覆盖to_param.默认值为to_param记录ID,但您可以更改它.
class Post
def to_param
"/#{year}/#{month}/#{slug}"
end
end
Run Code Online (Sandbox Code Playgroud)
(这假设您在Post类中有方法year,month和slug.)
现在,当生成URL时,to_param将调用被覆盖的内容.
<%= link_to @post.title, @post %>
=> <a href="/2010/02/foobar">Foobar</a>
Run Code Online (Sandbox Code Playgroud)
显然,你必须确保你的PostsController show动作可以根据传递的参数找到记录.
您可能需要更改路径定义并消除此路线:
map.post '/:year/:month/:slug, :controller => :posts, :action => :show
Run Code Online (Sandbox Code Playgroud)
但是,通过to_param覆盖,默认RESTful post_path将适用于您要生成的URL.
如何固定url_for的PostsController?可能不是很优雅,但它是干的,事情应该工作.
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
protected
def url_for(options = {} )
if options[:year].class.to_s == "Post"
obj = options[:year]
options[:year] = obj.year
options[:month] = obj.month
options[:slug] = obj.slug
end
super(options)
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4248 次 |
| 最近记录: |