モデルの属性の組み合わせでフィルタリングしたいモデルのインデックス ビューがあります。
たとえば、受取人やステータスでフィルター処理できる Bill モデル (アヒルのようなものではなく、支払わなければならないようなもの) があります。
モデルには、個々の属性ごとにスコープがあります。
scope :bill_status, lambda {|status| where("status = ?", status}
scope :bill_payee, lambda {|payee| where("payee_id = ?", payee.id}
このビューでは、ユーザーは0 個以上のオプションを選択できます。オプションが選択されていない場合は、「これでフィルタリングしない」ことを意味します。
コントローラーでは、次のような厄介なことを行うことができます。
def index
status = params[:bill][:status]
payee = params[:bill][:payee]
if status.present? and payee.present?
# chain scopes
@bills = Bill.bill_status(status).bill_payee(payee)
elsif status.present?
@bills = Bill.bill_status(status)
elsif payee.present?
@bills = Bill.bill_payee(payee)
else
@bills = Bill.all
end
# rest of controller action
end
しかし、これは機能しますが、きれいでも簡単に拡張できるわけでもありません。3 番目のフィルターを追加することで、より多くの可能性が得られます。私は美しさと純粋さを求めています。
私のスコープがすべて連鎖可能であると仮定すると、次のようなことができるはずです
def index
@bills = Bill.all
@bills = @bills.bill_status(params[:bill][:status]) if params[:bill][:status].present?
@bills = @bills.bill_payee(params[:bill][:payee]) if params[:bill][:payee].present?
# rest of controller code
end
Bill.all
配列であるため、機能しません。Bill.all
さらに、 AREL マジックのおかげで一度だけ実行したいクエリを実行するので、それは面白くありません。(条件なしで)のようなスコープを定義する必要がありますall_bills
-それはActiveRecord::Relation
私が推測する...
この問題をよりエレガントに解決するパターンはありますか? モデル、ビュー、およびコントローラーに依存する何かを実行するコードがあるときはいつでも、何か間違ったことをしているのではないかと感じます。または、私よりも賢くて一生懸命働いている誰かがすでにそれを解決したかのように:-)
おまけの質問: これはすべて、私が選んだ最も優れたカミナリの宝石であるページネーターで動作するようにしたい.
すべての考えやアイデアを歓迎します。