2017-08-09 13 views
0

Orderモデルのアプリケーションがあり、PurchaserSupplierに接続しています。このアプリケーションは、これらの会社との提携関係に基づいて、注文を作成/更新/破棄できる人を制限するように設計されています。 (例えば、購入者が注文をすることはできますが、サプライヤーのメンバーはできません)ユーザーごとの強力なパラメータのベストプラクティス?

私はこれらの認証ルールを強力なパラメータを介してコントローラレベルで強制しています。私の理由は2つある:before_saveコールバック(または他のモデル・ロジック)にそれらを延期

  1. (それが属する)コントローラからパラメータスクリーニングを除去するであろう。そして
  2. でも、コントローラーから追加の情報(ユーザーID)をモデルに渡す必要があり、より密接に結合されたクラスにつながります。

現在、私の強いのparamロジックは次のようになります。

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) && [email protected]? 
     p.merge!(params[:order].permit(:notes)) 
    end 
    end 
end 

私はそれがひどく読めないと思います。強力なパラメータにいくつかの認可ロジックを適用するためのよりクリーンな(または広く受け入れられている)パターンがありますか?代わりに、これは間違った抽象化ですか?結局のところ、この承認をモデルに延期するべきですか?

答えて

1

[購入者または仕入先]にはいくつかの権限があるため、そのような行為を許可された唯一の権限であるため、[[購入者]または[仕入先]購入者または仕入先]クラスのいずれかを選択します。例えば

購入者は、各オブジェクトは、それが実行する必要が責任を持つように、買付者クラスの作成、注文方法を置くことは合理的であるように、注文を作成するだけですので、これらのメソッドはカプセル化されていないため、これらのメソッドは他のエンティティによって持ち越されたりアクセスされたりすることはできません。

オブジェクト指向のアプローチを考え、「単一責任の原則」を考えれば、コードをより整理しやすくすることができます。

+0

これは私が考えていたものです。私が正しく理解していれば、このアプローチは強力なパラメータと互換性がありません。 (つまり、2つのクラスは異なるパラメータを必要とするかもしれませんが、コントローラはそれらを区別しないので、必要なすべてのパラメータを渡す必要があります...) –

+0

はい、それは強い各クラスの責任に関連しています。 intコントローラアクションでは、強力なパラメータを使用して、テーブルの作成や更新(create、updateなどを使用)に必要なパラメータ以外のパラメータが含まれないようにする必要があります。 –

+0

コントローラでホワイトリストパラメータを指定し、必要なクラスタイプのオブジェクトを定義し、タスクの実行とプロセスの完了を担当するオブジェクトのメソッドにパラメータを委譲することができます。 あなたは必要に応じてそれを行うことができます。私はあなたに例を挙げています。すべてを実装して整理する方法を選ぶことはすべてあなた次第です。 –

関連する問題