Order
モデルのアプリケーションがあり、Purchaser
とSupplier
に接続しています。このアプリケーションは、これらの会社との提携関係に基づいて、注文を作成/更新/破棄できる人を制限するように設計されています。 (例えば、購入者が注文をすることはできますが、サプライヤーのメンバーはできません)ユーザーごとの強力なパラメータのベストプラクティス?
私はこれらの認証ルールを強力なパラメータを介してコントローラレベルで強制しています。私の理由は2つある:before_save
コールバック(または他のモデル・ロジック)にそれらを延期
- (それが属する)コントローラからパラメータスクリーニングを除去するであろう。そして
- でも、コントローラーから追加の情報(ユーザー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
私はそれがひどく読めないと思います。強力なパラメータにいくつかの認可ロジックを適用するためのよりクリーンな(または広く受け入れられている)パターンがありますか?代わりに、これは間違った抽象化ですか?結局のところ、この承認をモデルに延期するべきですか?
これは私が考えていたものです。私が正しく理解していれば、このアプローチは強力なパラメータと互換性がありません。 (つまり、2つのクラスは異なるパラメータを必要とするかもしれませんが、コントローラはそれらを区別しないので、必要なすべてのパラメータを渡す必要があります...) –
はい、それは強い各クラスの責任に関連しています。 intコントローラアクションでは、強力なパラメータを使用して、テーブルの作成や更新(create、updateなどを使用)に必要なパラメータ以外のパラメータが含まれないようにする必要があります。 –
コントローラでホワイトリストパラメータを指定し、必要なクラスタイプのオブジェクトを定義し、タスクの実行とプロセスの完了を担当するオブジェクトのメソッドにパラメータを委譲することができます。 あなたは必要に応じてそれを行うことができます。私はあなたに例を挙げています。すべてを実装して整理する方法を選ぶことはすべてあなた次第です。 –