每用户强参数的最佳实践?

时间:2017-08-09 10:12:01

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

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

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

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

    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
    

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

1 个答案:

答案 0 :(得分:1)

由于每种类型[购买者或供应商]都有某些权限[或要做的功能]而且它是唯一获得此类行为授权的人,因此我建议您将每种类型的任务作为一种方法放在[购买者]中或供应商]类别取决于哪一方必须执行此方法或任务。

例如:

由于买方只是创建订单的人,因此在买方类中放置创建订单方法是合理的,这样每个对象都有其需要承担的责任,并且这些方法无法承载或由任何其他实体访问,因为它们没有封装在其中的这些方法。

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