1

モデルの属性の組み合わせでフィルタリングしたいモデルのインデックス ビューがあります。

たとえば、受取人やステータスでフィルター処理できる 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私が推測する...

この問題をよりエレガントに解決するパターンはありますか? モデル、ビュー、およびコントローラーに依存する何かを実行するコードがあるときはいつでも、何か間違ったことをしているのではないかと感じます。または、私よりも賢くて一生懸命働いている誰かがすでにそれを解決したかのように:-)

おまけの質問: これはすべて、私が選んだ最も優れたカミナリの宝石であるページネーターで動作するようにしたい.

すべての考えやアイデアを歓迎します。

4

2 に答える 2

4

私はこのようなことをします:

proxy = Bill.scoped
if status.present?
  proxy = proxy.bill_status(status)
end
if payee.present?
  proxy = proxy.bill_payee(payee)
end

@bills = proxy

次に、いくつかのメタプログラミングを行うこともできます。

@bills = [:status, :payee, ...].inject(Bill.scoped) do |proxy, param|
  val = params[:bill][param]
  val.present ? proxy.send("bill_#{param}", val) : proxy
end
于 2012-08-06T09:54:22.613 に答える
1

一般的な問題のように思われる問題の解決策を探しているときに、Ryan BatesのRailsCastをチェックして、3日前のエピソードをRansackで見つけました。Ransackは、フォーム検索と列の並べ替えに非常に優れた優れた製品であり、それが私が行っている方法だと思います。

ここでの回答に感謝します-回答に時間と労力を費やした人々からいくつかの素晴らしいテクニックを学んだことをうれしく思います。

于 2012-08-06T13:01:32.597 に答える