1

実行時にスコープを動的に組み合わせて、ユーザー入力に基づいてカスタム クエリを作成できるようにしたいと考えています。Book モデルのライブラリ アプリケーションがあり、次のスコープが定義されているとしますchecked_out, fiction, non_fiction, overdue, and checked_out_by

,はlast scopechecked_out_by引数として library_user_id を取るラムダです。このアプリケーションにより、ライブラリアンは、ユーザー入力に基づいて、これらのスコープを動的に組み合わせたさまざまな種類のクエリを実行できます。したがって、司書がチェックアウトされたすべてのノンフィクションの本を示すレポートを作成したい場合は、次のように簡単に実行できます。

criteria = ["non_fiction", "checked_out"]  <= array built based on what the user selected  
books = Book.scoped  
criteria.each {|criteria| books = books.send(criteria)}  

しかし、ラムダとして設定されたスコープでこれを行うにはどうすればよいですか? たとえば、ユーザーが期限切れで特定の人によってチェックアウトされた本を表示するクエリを作成したい場合はどうでしょうか。この場合、criteria 配列に「overdue」スコープと「checked_out_by」スコープを含めたいのですが、ラムダ スコープでそれを設定する方法がわかりません。私は試した:

criteria = ["non_fiction", {:checked_out_by => 6}]  

しかし、それは私に「{:checked_out_by => 6} is not a symbol」というエラーを与えます。私も試しました

criteria = ["non_fiction", [checked_out_by, 6]]

および他のいくつかの亜種がありましたが、どれも機能しませんでした。誰もこれを行う方法を知っていますか?

4

1 に答える 1

1

パラメータは、2 番目のパラメータとして に送信できますsend。あなたの例に基づいて、次のようなことができます:

criteria = [:non_fiction, { checked_out_by: 6 }]

criteria.each do |c|
  case c
    when Hash then c.keys.each { |key| books = books.send key, c[key] }
    when Symbol then books = books.send c
  end
end

OpenStructまたは、 の代わりに を使用できますHash

   criteria = [:non_fiction, OpenStruct.new(key: :checked_out_by, value: 6)]

   criteria.each do |c|
      books = case c
        when OpenStruct then books.send c.key, c.value
        when Symbol then books.send c
      end
    end

または、さらに良いのは、必要なキーと値を持つクラスを作成することです。

于 2013-03-29T22:50:42.253 に答える