我有一个模型 Report,它是多态的。 我网站上的很多 itens 可能有很多。
我想要一个通用的 Controller 来发布它。 它是一个非常简单的模型,只有一条文本消息和关联。
在我的 route ,我正在做类似的事情
map.resources :users, :has_many => [ :reports ]
map.resources :posts, :has_many => [ :reports ]
但在我的 reports_controller 中,我想从它的来源中获取关系。
喜欢:
before_filter :get_reportable
def get_reportable
reportable = *reportable_class*.find params[:reportable_id]
end
这可能吗?
我如何获得 reportable_class 和 reportable_id?
当它来自用户 Controller 时,我可以获得 params[:user_id],或者当它来自帖子时,我可以获得 params[:post_id]。我可以对所有关系做一个案例,但它似乎根本不是一个干净的解决方案......
有多态关联是最好的,有什么办法吗?
最佳答案
如果您有一个 Controller 通过两个不同的路径处理请求,那么您需要让它知道调用它的上下文。你经常会看到很多看起来像这样的代码:
before_filter :load_reportable
def load_reportable
if (params[:user_id])
@user = User.find(params[:user_id])
@reportable = @user
elsif (params[:post_id])
@post = Post.find(params[:post_id])
@reportable = @post
end
rescue ActiveRecord::RecordNotFound
render(:partial => 'not_found', :status => :not_found)
return false
end
由于您使用的是多态关联,因此您可以改为执行以下操作:
before_filter :load_reportable
def load_reportable
unless (@reportable = @report.reportable)
# No parent record found
render(:partial => 'not_found', :status => :not_found)
return false
end
# Verify that the reportable relationship is expressed properly
# in the path.
if (params[:user_id])
unless (@reportable.to_param == params[:user_id])
render(:partial => 'user_not_found', :status => :not_found)
return false
end
elsif (params[:post_id])
unless (@reportable.to_param == params[:post_id])
render(:partial => 'post_not_found', :status => :not_found)
return false
end
end
end
这种方法的问题在于,您有一个 Controller 为两条完全不同的路由提供服务,它会生成错误消息,例如“找不到用户”与“找不到帖子”。例如,如果您不是从 Users::BaseController 继承,这可能很难做到正确。
在许多情况下,创建两个独立的“报告” Controller 更容易,例如用户/报告和帖子/报告,其中任何通用功能都从模块中导入。这些 Controller 通常继承自执行加载和错误处理的基本 Controller 。基本 Controller 还可以建立布局、页面标题等,而无需为每个子资源 Controller 重新实现此功能。
另一种方法是分离报告,让它作为自己的 Controller 运行,其中与“可报告”记录的关系大多不相关。
关于ruby-on-rails - Rails 多态关联和路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2071979/