我正在开发一个Rails应用程序,我有几个操作(#delete_later,#ban_later等),我只在请求参数中设置一个属性(具体来说,一个reason
字段用于执行该操作)。
我想知道是否可以这样做:
def ban_later
@object.reason = params[:object][:reason]
@object.save
end
或者即使在这种情况下使用强制参数也是最佳做法?
def ban_later
@object.reason = object_params[:reason]
@object.save
end
private
def object_params
params.require(:object).permit(:permitted_1, :permitted_2, :reason)
end
哪种解决方案最好?如果没有,那么问题的最佳解决方案是什么?
稍后编辑:
#ban_later,#delete_later动作确实可以设置一个标志列status
,但这可以在不从params散列中接收它的值的情况下完成。由于您只为每个方法设置一个状态,因此当您在#delete_later时可以设置状态“pending_delete”,当您在#ban_later时,可以设置“pending_ban”。
稍后编辑
为什么直接使用#save
而不是update_attributes
?假设您需要if @object.save
语句。在false分支(对象未保存)上,您可能仍希望呈现使用@object
内容的视图。
答案 0 :(得分:1)
首先保存计算。
第二个检查是否存在:object sub-hash,我认为这对容错有好处。
我最初会选择第一名,但经过一番思考后我更喜欢第二名。
答案 1 :(得分:1)
最简单的答案是,如果您只在params
中使用一个参数,并且未将其传递给多个属性设置器,例如model#create
,那么您不必使用strong_parameters来获取安全的解决方案。
但是,我预计整个控制器不太可能出现这种情况。 ban_later
方法只需要一个参数,其他控制器方法需要更多。在这种情况下,问题变为:"您是否希望params
以不同的方式处理ban_later
如何将其用于其他控制器方法?"。
您还可以确定功能不会更改,并且当您更改功能时,您将会记住更改params
的处理方式。
因此,我会使用strong_parameters,因为它意味着:
答案 2 :(得分:1)
如果您要更新单个属性,为什么不使用 update_attributes
方法? (update_attribute
不会调用验证)
def ban_later
@object.update_attributes reason: params(:reason)
end
private
def params params
params = %i(:permitted_1, :permitted_2, :permitted_3) unless params
params.require(:object).permit params
end
根据ReggieB
的评论,您还可以使用update
选项:
def ban_later
@object.update reason: params(:reason)
end
如上所述,Reggie和其他答案解释了这种方法的最佳工作原理(IE与mass-assignment
等)。以上是您可以自由使用的可操作代码。
这里的底线是,如果您希望保持您的应用程序通用(IE具有最终可扩展性,无论您需要),您需要遵守强参数设置。
其他答案概述了该设置的工作原理,以及其功能如何根据您的需要而有所不同。
我已经包含了一个技巧,所以你只接受params方法中的特定参数。我没有对它进行过广泛的测试,因此我们可能需要对其进行重构以获得所需的结果。
答案 3 :(得分:1)
强参数检查后,为什么不只是update
对象?它只是一个标准的工作流程。 (请告诉我在你的情况下是否有任何理由不这样做)
def ban_later
@object.update(object_params)
# dont forget validation check
end
private
def object_params
params.require(:object).permit(:permitted_1, :permitted_2, :reason)
end
在这种情况下,添加更多可更新字段会更容易。