Aufbau Aktiver Datensatz die Bedingungen in einem array - private Methode 'scan' genannt-Fehler
Frage
Ich bin versucht, zu erstellen eine Reihe von Bedingungen dynamisch ein array verwenden, wie vorgeschlagen, in der ersten Antwort hier: Ein oder mehrere Parameter im Modell finden Sie Bedingungen, die mit Ruby on Rails.Allerdings scheine ich zu tun etwas falsch und ich bin mir nicht sicher, ob das, was ich versuche, ist grundsätzlich ungesund oder wenn ich einfach botching meine syntax.
Ich bin Vereinfachung nur noch eine einzige Bedingung hier, um zu versuchen, zur Verdeutlichung des Problems habe ich versucht zu bauen einen einfachen Proof-of-concept über diese Zeilen, bevor Schichtung auf der 5 verschiedenen Zustand styles ich bin der Auseinandersetzung mit.
Das funktioniert:
excluded.push 12
excluded.push 30
@allsites = Site.all(:conditions => ["id not in (?)", excluded])
Diese Ergebnisse in eine private Methode 'scan' genannt-Fehler:
conditionsSet = []
excluded.push 12
excluded.push 30
conditionsSet << ["id not in (?)", excluded]
@allsites = Site.all(:conditions => conditionsSet)
Vielen Dank für jeden Rat.Ich war nicht sicher, ob das die richtige Sache war es, dies als Nachfolge-Artikel zu den Fragen/Antworten, die ich notiert an der Spitze.Da habe ich ein problem keine Antwort.Wenn es einen besseren Weg, um diese post mit Bezug auf die bestehende post bitte lassen Sie mich wissen.
Lösung
Versuchen Sie dies:
Rails 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
Jetzt irgendwo in Ihrem controller:
Site.all(:conditions => Site.build_conditions([1,2]))
Site.all(:conditions => Site.build_conditions(nil, "ABC"))
Rails 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
Jetzt irgendwo in Ihrem controller:
Site.exclude_ids_by_name_and_state([1,2])).all
Site.exclude_ids_by_name_and_state(nil, "ABC").all
Andere Tipps
Sie möchten:
conditionsSet += ["id not in (?)", excluded]
statt:
conditionsSet << ["id not in (?)", excluded]
+=
fügt die zwei arrays zusammen (denken Sie an es als eine Zusammenlegung der beiden in einem array), während <<
schiebt ein neues element in das array.So sind Sie immer: [["id not in (?)", excluded]]
bei der Verwendung von <<
, und :conditions
will ein array, wobei das erste element eine Zeichenfolge ist (kein array).
Versuchen Sie es SmartTuple, es ist speziell für Fälle wie diese.
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")
Für mich ist es auch vorzuziehen zu verwenden options
hash anstelle der bestellten Argumente.Wie das Projekt wächst, mehr Bedingungen können angezeigt und Sie werden verlieren track von, die kommt.Hash-sieht aus und verhält sich klarer, und Sie können leicht überprüfen, um zu vermeiden, Fehler der software.