我有一个模型,报告,这是多态的。 在我的网站上有这么多的itens可能有很多。
我希望有一个通用的控制器来发布它。 它是一个非常简单的模型,只有一条短信和关联。
在我的路线中,我正在做类似
的事情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?
当来自用户控制器时,我可以得到params [:user_id],或者当它来自帖子时,我可以得到params [:post_id]。我可以对所有关系做一个案例,但它看起来根本不是一个干净的解决方案......
具有多态关联将是最好的,有什么方法?
答案 0 :(得分:4)
如果您有一个控制器通过两个不同的路径处理请求,那么您需要让它知道它将被调用的上下文。您经常会看到很多类似的代码:
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继承,这可能很难做到。
在许多情况下,创建两个独立的“报告”控制器比较容易,例如用户/报告和帖子/报告,其中从模块导入任何常用功能。这些控制器通常从执行加载和错误处理的基本控制器继承。基本控制器还可以建立布局,页面标题等,而无需为每个子资源控制器重新实现此功能。
另一种方法是解除报告并将其作为自己的控制器运行,其中与“可报告”记录的关系几乎无关紧要。
答案 1 :(得分:0)
或尝试:
before_filter :get_reportable
def get_reportable
params.each do |name, value|
if name =~ /(.+)_id$/
@reportable = $1.classify.constantize.find(value)
end
end
end
它正在通过所有参数并试图找到一个以_id结尾,然后在部分之前抓住它并找到相关记录。