我必须在我的应用程序中做类似的事情。我接受了我想出的东西并对其进行了一些更改,但我尚未对其进行测试,因此请小心使用。它不漂亮,但它比我能想到的其他任何东西都要好。
在 routes.rb 中:
resources :posts, :pictures
controller :comments do
get '*path/edit' => :edit, :as => :edit_comment
get '*path' => :show, :as => :comment
# etc. The order of these is important. If #show came first, it would direct /edit to #show and simply tack on '/edit' to the path param.
end
在comment.rb 中:
embedded_in :commentable, :inverse_of => :comments
def to_param
[commentable.class.to_s.downcase.pluralize, commentable.id, 'comments', id].join '/'
end
在 comments_controller.rb 的前置过滤器中:
parent_type, parent_id, scrap, id = params[:path].split '/'
# Security: Make sure people can't just pass in whatever models they feel like
raise "Uh-oh!" unless %w(posts pictures).include? parent_type
@parent = parent_type.singularize.capitalize.constantize.find(parent_id)
@comment = @parent.comments.find(id)
好了,丑事结束。现在您可以向任何您想要的模型添加注释,并且只需执行以下操作:
edit_comment_path @comment
url_for @comment
redirect_to @comment
等等。
编辑:我没有在我自己的应用程序中实现任何其他路径,因为我需要的只是编辑和更新,但我想它们看起来像:
controller :comments do
get '*path/edit' => :edit, :as => :edit_comment
get '*path' => :show, :as => :comment
put '*path' => :update
delete '*path' => :destroy
end
其他动作会更棘手。您可能需要执行以下操作:
get ':parent_type/:parent_id/comments' => :index, :as => :comments
post ':parent_type/:parent_id/comments' => :create
get ':parent_type/:parent_id/comments/new' => :new, :as => :new_comment
然后,您将使用 params[:parent_type] 和 params[:parent_id] 访问控制器中的父模型。您还需要将正确的参数传递给 url 助手:
comments_path('pictures', 7)