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.

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top