如果你有一个控制器通过两个不同的路径处理请求,那么你需要让它知道调用它的上下文。你经常会看到很多看起来像这样的代码:
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
这种方法的问题是,您有一个控制器服务于两条完全不同的路线,它会生成错误消息,例如“找不到用户”与“找不到帖子”。例如,如果您没有从 Users::BaseController 继承,这可能会很棘手。
在许多情况下,创建两个独立的“报告”控制器会更容易,例如用户/报告和帖子/报告,其中任何常见的功能都是从模块中导入的。这些控制器通常继承自执行加载和错误处理的基本控制器。基本控制器还可以建立布局、页面标题等,而不必为每个子资源控制器重新实现此功能。
另一种方法是分离报告并让它作为自己的控制器运行,其中与“可报告”记录的关系大多无关紧要。