Domanda

Sto tentando di costruire un insieme di condizioni in modo dinamico utilizzando un array come suggerito nella prima risposta qui: Uno o più parametri nel modello di trovare condizioni con Ruby on Rails.Tuttavia mi sembra di fare qualcosa di sbagliato e non so se quello che sto cercando è fondamentalmente falsi o se sono semplicemente botching la mia sintassi.

Sto semplificando in una singola condizione qui per cercare di illustrare il problema, come ho cercato di costruire una semplice Prova di concetto, lungo queste linee di stratificazione su 5 condizioni diverse stili sto affrontando.

Questo funziona:

excluded.push 12
excluded.push 30
@allsites = Site.all(:conditions => ["id not in (?)", excluded])

Questo si traduce in un metodo privato 'scan' chiamato errore:

conditionsSet = []
excluded.push 12
excluded.push 30
conditionsSet << ["id not in (?)", excluded]
@allsites = Site.all(:conditions => conditionsSet)

Grazie per qualsiasi consiglio.Non ero sicuro se la cosa migliore era mettere questo come un elemento di follow-up per le relative domande/risposte che ho indicato all'inizio.Dal momento che ho un problema, non una risposta.Se c'è un modo migliore di questo post relativi al post esistente, per favore fatemelo sapere.

È stato utile?

Soluzione

Prova questo:

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

Ora, da qualche parte nel vostro 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

Ora, da qualche parte nel vostro controller:

Site.exclude_ids_by_name_and_state([1,2])).all 
Site.exclude_ids_by_name_and_state(nil, "ABC").all

Altri suggerimenti

Si desidera:

conditionsSet += ["id not in (?)", excluded]

invece di:

conditionsSet << ["id not in (?)", excluded]

+= aggiunge i due matrici insieme (pensare ad esso come l'unione di due in un array), mentre << inserisce un nuovo elemento in un array.In modo che si stanno ottenendo: [["id not in (?)", excluded]] quando si utilizza <<, e :conditions vuole un array in cui questo primo elemento è una stringa, non un array).

Provare SmartTuple, progettato specificamente per casi come questo.

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")

Per me è anche preferibile utilizzare options hash invece ordinato argomenti.Man mano che il progetto cresce, più condizioni possono apparire e si perde traccia di quale arriva che.Hash sembra e si comporta più chiara, più facilmente si può convalidare, per evitare gli errori del software.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top