当我们只更新一个属性时,我们应该使用强对数吗?

时间:2015-10-13 06:04:10

标签: ruby-on-rails ruby strong-parameters mass-assignment

我正在开发一个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内容的视图。

4 个答案:

答案 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

在这种情况下,添加更多可更新字段会更容易。