我试图使用瘦控制器和胖模型付诸实践,但是为了做到这一点,我发现自己需要将其他变量传递给.create方法。
所以例如我在哪里:
@app = App.new(app_params)
def app_params
params.require(:app).permit( :name, :description)
end
现在我还想传递一个会话持有user_id,以及对权限组的引用。所以希望类似下面的伪代码:
@app = App.create(app_params, session[:user_id], app_permission_id)
user_id和app_permission_id不会被持久化但是可用我希望在模型中的after_create回调之类的地方,所以我可以做一些进一步的工作,例如创建创建的日志条目,与主叫用户相关联。
我不太热衷于将它们作为隐藏字段添加到表单中(以隐藏用户的实现)。我认为有一种可能的方法使用.merge?如果是这样的话,我猜我会用虚拟属性将它们拉出来。
非常感谢有关最佳/最干净方法的任何建议。我想我不得不以某种方式覆盖.create方法(但仅限于控制器端最干净的实现方式)。
答案 0 :(得分:5)
如果您是app_params,则应始终包含user_id和app_permission_id
你应该这样做
def app_params
params.require(:app).permit( :name, :description).merge(user_id: session[:user_id], app_permission_id: app_permission_id)
end
否则,如果它不应该一直包含这个
你应该这样做
app_params.merge(user_id: session[:user_id], app_permission_id: app_permission_id) #as mentioned by Vapire in his answer
答案 1 :(得分:1)
是的,这可以通过merge
def create
@app = App.new(app_params.merge(user_id: session[:user_id], app_permission_id: app_permission_id))
end
当然,您的模型中需要虚拟属性user_id
和app_permission_id
。
另见this answer。
答案 2 :(得分:1)
描述.merge
的两个答案是正确的;让我解释原因
-
<强> PARAMS 强>
在控制器级别处理params并使用strong_params
进行处理时,Rails基本上是&#34;通过&#34;将数据传递到您的模型,如下所示:
"params" => {
"app" => {
"name" => "data",
"description" => "data",
}
}
这是典型的form_for
参数对象通过控制器发送的内容。当您通过strong_params
方法获取数据时,您基本上只是&#34;允许&#34;要传递给模型的各种数据。
请注意,strong_params
旨在帮助阻止mass_assignment
,这意味着该方法旨在仅向您的模型发送特定的参数。
-
<强>修正强>
如果您想为每个模型请求附加额外数据,您必须使用merge
:
def app_params
params.require(:app).permit(:name, :description).merge(user_id: session[:user_id], app_permission_id: app_permission_id)
end