【问题标题】:Best practice for per-user strong parameters?每个用户强参数的最佳实践?
【发布时间】:2017-08-09 10:12:00
【问题描述】:

我有一个带有Order 模型的应用程序,连接到PurchaserSupplier。该应用程序旨在限制谁可以创建/更新/销毁订单,具体取决于他们与这些公司的隶属关系。 (例如,采购员的成员可以创建订单,但供应商的成员不能。)

我正在通过强参数在控制器级别执行这些授权规则。我的理由是双重的:

  1. 将它们推迟到before_save 回调(或其他模型逻辑)会从控制器(它所属的位置)移除参数筛选;和
  2. 即便如此,我也必须将额外的信息(即用户身份)从控制器传递给模型才能完成,这将导致更紧密耦合的类。

目前,我的强参数逻辑如下所示:

def create_order_params
  params.require(:order).permit(:supplier_id, :purchaser_id, :notes)
    .merge({ placed_by: current_user })
end

def update_order_params
  params.require(:order).permit().tap do |p|
    p.merge!({ accepted_by: current_user }) if params.dig(:order, :accepted)
    if current_user.belongs_to?(@order.supplier)
      p.merge!(params[:order].permit(:discount, :discount_type))
    end
    if current_user.belongs_to?(@order.purchaser) && !@order.confirmed?
      p.merge!(params[:order].permit(:notes))
    end
  end
end

我认为它非常难以阅读。是否有更简洁(或被广泛接受)的模式将一些授权逻辑应用于强参数?或者,这是错误的抽象吗?毕竟我应该将此授权推迟到模型吗?

【问题讨论】:

    标签: ruby-on-rails authorization strong-parameters


    【解决方案1】:

    由于每种类型 [Purchasers 或 Suppliers] 都有一些权限 [或功能要做],并且是唯一有权执行此类操作的人,因此我建议您将每种类型的任务作为方法放在 [Purchasers或 Suppliers] 类,具体取决于哪个必须执行此方法或任务。

    例如:

    由于采购者只是创建订单的人,所以在采购者类中放置一个创建订单方法是合理的,这样每个对象都有它需要承载的职责,而这些方法不能承载或任何其他实体都可以访问,因为它们没有封装这些方法。

    以面向对象的方式思考,并考虑“单一责任原则”,将引导您更好地组织和使代码更干净。

    【讨论】:

    • 这就是我的想法。如果我理解正确,这种方法与强参数不兼容,对吧? (这两个类可能需要不同的参数,但由于控制器不区分它们,它需要传递可能需要的任何和所有参数......)
    • 是的,跟强参数无关,跟每个类的职责有关。在控制器操作中,您需要使用强参数来确保除了用于创建或更新表(使用 create、update .. 等)所需的参数之外,不包含任何参数。
    • 您可以将控制器中的参数列入白名单,然后定义您想要的类类型的对象,并将参数委托给该对象的方法,该方法负责承载任务并完成该过程。你可以根据需要按照你想要的方式来做,我只是给你一个例子,一切都取决于你选择如何实现和组织它。
    猜你喜欢
    • 2019-04-02
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    相关资源
    最近更新 更多