配列内でのアクティブ レコード条件の構築 - プライベート メソッド 'scan' でエラーが呼び出されました
質問
ここの最初の回答で提案されているように、配列を使用して一連の条件を動的に構築しようとしています。 Ruby on Rails でのモデル検索条件内の 1 つ以上のパラメータ. 。しかし、私は何かを間違っているようで、私がしようとしていることが根本的に間違っているのか、それとも単に構文を間違えているのかわかりません。
ここでは問題を説明するために 1 つの条件に単純化しています。これは、私が取り組んでいる 5 つの異なる条件スタイルを重ねる前に、これらの方針に沿って単純な概念実証を構築しようとしているからです。
これは機能します:
excluded.push 12
excluded.push 30
@allsites = Site.all(:conditions => ["id not in (?)", excluded])
これにより、プライベート メソッド「scan」の呼び出しエラーが発生します。
conditionsSet = []
excluded.push 12
excluded.push 30
conditionsSet << ["id not in (?)", excluded]
@allsites = Site.all(:conditions => conditionsSet)
アドバイスをありがとうございます。冒頭に記した関連する質問と回答のフォローアップ項目としてこれを記載するのが適切かどうかわかりませんでした。答えではなく問題があるので。既存の投稿に関連してこれを投稿するより良い方法がある場合は、お知らせください。
解決
これを試して:
レール2.3
class Site < ActiveRecord::Base
def self.build_conditions(ids, name=nil, state=nil)
cond = []
cond << send(:sanitize_sql_array, ["id NOT IN (?)", ids]) unless ids.empty?
cond << send(:sanitize_sql_array, ["name = ? ", name]) unless name
cond << send(:sanitize_sql_array, ["state = ? ", state]) unless state
cond.join(" and ")
end
end
コントローラーのどこかに次のようにします。
Site.all(:conditions => Site.build_conditions([1,2]))
Site.all(:conditions => Site.build_conditions(nil, "ABC"))
レール 3
class Site < ActiveRecord::Base
def self.exclude_ids_by_name_and_state(ids, name=nil, state=nil)
result = scoped
result = result.where("id NOT IN (?)", ids) if ids.present?
result = result.where(:name => name) if name.present?
result = result.where(:state => state) if state.present?
result
end
end
コントローラーのどこかに次のようにします。
Site.exclude_ids_by_name_and_state([1,2])).all
Site.exclude_ids_by_name_and_state(nil, "ABC").all
他のヒント
あなたが欲しいます:
conditionsSet += ["id not in (?)", excluded]
の代わりに:
conditionsSet << ["id not in (?)", excluded]
+=
がアレイ上に新しい要素を押しながら <<
は、(2つの1にアレイをマージと考える)2つの配列を付加します。 [["id not in (?)", excluded]]
を使用した場合<<
を、そして:conditions
は、この最初の要素が文字列(いない配列)である配列を望んでいる。
試してみてください SmartTuple に、それはこのような場合のために特別に設計されています。
def self.build_conditions(options = {})
[
SmartTuple.new(" AND "),
(["id NOT IN (?)", ids] if options[:ids].present?),
({:name => options[:name]} if options[:name].present?),
({:state => options[:state]} if options[:state].present?),
].sum.compile
end
...
Site.all(:conditions => Site.build_conditions(:ids => {1,2]))
Site.all(:conditions => Site.build_conditions(:name => "abc", :state => "disabled")
私にはそれがoptions
ハッシュの代わりに注文した引数を使用することもpreferrableです。あなたのプロジェクトが成長するにつれて、より多くの条件が表示されることがあり、あなたが来ているのトラックを失うことになります。ハッシュルックスと振る舞う明確なプラスあなたは簡単にソフトウェアのエラーを回避するために、それを検証することができます。