有没有人有任何管理Rails 3中的多态嵌套资源的技巧?

Rya*_*yan 7 polymorphism nested-resources mongoid ruby-on-rails-3

在config/routes.rb中:

resources :posts do
  resources :comments
end

resources :pictures do
  resources :comments
end
Run Code Online (Sandbox Code Playgroud)

我想允许更多的事情被评论.

我目前正在使用mongoid(mongomapper并不像我想的那样与Rails 3兼容),而注释是一个嵌入式资源(mongoid还不能处理多态关系资源),这意味着我确实需要父资源为了找到评论.

有没有优雅的方法来处理以下一些问题:

在我的控制器中,我需要在找到评论之前找到父母:

if params[:post_id]
  parent = Post.find(params[:post_id]
else if params[:picture_id]
  parent = Picture.find(params[:picture_id]
end
Run Code Online (Sandbox Code Playgroud)

如果我开始添加更多可评论的内容,那将会变得混乱.

url_for([comment.parent, comment])不起作用,所以我将不得不在我的Comment模型中定义一些东西,但我认为我还需要在Comment模型中定义索引路径以及可能的编辑和新路由定义.

随着我的进一步发展,我可能会遇到更多问题.

我无法想象我是第一个尝试解决这个问题的人,是否有任何解决方案可以使其更易于管理?

Pre*_*ids 4

我必须在我的应用程序中做类似的事情。我把我想出的东西做了一些改变,但我还没有测试过,所以请小心使用。它不漂亮,但比我能想到的任何东西都要好。

在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
Run Code Online (Sandbox Code Playgroud)

在评论.rb中:

embedded_in :commentable, :inverse_of => :comments

def to_param
  [commentable.class.to_s.downcase.pluralize, commentable.id, 'comments', id].join '/'
end
Run Code Online (Sandbox Code Playgroud)

在 comments_controller.rb 的 before 过滤器中:

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)
Run Code Online (Sandbox Code Playgroud)

好吧,丑陋结束了。现在您可以向任何您想要的模型添加注释,只需执行以下操作:

edit_comment_path @comment
url_for @comment
redirect_to @comment
Run Code Online (Sandbox Code Playgroud)

等等。

编辑:我没有在自己的应用程序中实现任何其他路径,因为我需要的只是编辑和更新,但我想它们看起来像这样:

controller :comments do
  get    '*path/edit' => :edit, :as => :edit_comment
  get    '*path'      => :show, :as => :comment
  put    '*path'      => :update
  delete '*path'      => :destroy
end
Run Code Online (Sandbox Code Playgroud)

其他动作会比较棘手。您可能需要执行以下操作:

  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
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用 params[:parent_type] 和 params[:parent_id] 访问控制器中的父模型。您还需要将正确的参数传递给 url 助手:

comments_path('pictures', 7)
Run Code Online (Sandbox Code Playgroud)