Question

Je tente de construire un ensemble de conditions dynamiquement en utilisant un tableau comme suggéré dans la première réponse ici: Un params ou plus dans le modèle trouvent des conditions avec Ruby on rails . Cependant, je semble faire quelque chose de manière incorrecte et je ne sais pas si ce que je suis en train est fondamentalement saine ou si je suis simplement bousiller ma syntaxe.

Je simplifie vers le bas à une seule condition ici pour essayer d'illustrer la question comme je l'ai essayé de construire une preuve simple concept le long de ces lignes avant la superposition des 5 différents styles de condition que je suis contestait avec.

Cela fonctionne:

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

Il en résulte une méthode privée 'scan' appelée erreur:

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

Merci pour tout conseil. Je ne sais pas si la bonne chose était de mettre cela comme un élément de suivi à la question / réponses connexes je l'ai noté en haut. Depuis que j'ai un problème pas une réponse. S'il y a une meilleure façon d'afficher ce lié au poste existant s'il vous plaît laissez-moi savoir.

Était-ce utile?

La solution

Essayez ceci:

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

quelque part dans votre contrôleur:

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

quelque part dans votre contrôleur:

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

Autres conseils

Vous voulez:

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

au lieu de:

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

+= ajoute les deux réseaux ensemble (le considérer comme fusionnant les deux dans une rangée), tandis que << pousse un nouvel élément sur le réseau. Donc, vous obtenez:. [["id not in (?)", excluded]] lors de l'utilisation << et :conditions veut un tableau où ce premier élément est une chaîne (pas un tableau)

SmartTuple , il a été conçu spécifiquement pour les cas comme celui-ci.

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

Pour moi, il est également préférable d'utiliser hachage options au lieu des arguments ordonnés. À mesure que votre projet se développe, plus les conditions peuvent apparaître et vous perdre de vue ce qui vient qui. Hash ressemble et se comporte plus clair, plus vous pouvez facilement le valider pour éviter les erreurs logicielles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top