2009-12-29 3 views
1

J'ai un modèle qui possède 2 propriétés: valid_from et valid_to.Utilisez les mêmes paramètres plusieurs fois dans des conditions de recherche: hachage

J'ai besoin de sélectionner toutes les instances qui sont actuellement valides, c'est-à-dire valid_from < = today et valid_to> = today.

i ont la découverte suivante:

Mymodel.find(:all, :conditions => ["valid_from <= ? and valid_to >= ?", Date.today, Date.today]) 

J'ai déjà pensé à stocker Date.today dans une variable et d'appeler cette variable, mais je dois encore appeler deux fois.

my_date = Date.today 
Mymodel.find(:all, :conditions => ["valid_from <= ? and valid_to >= ?", my_date, my_date]) 

Y at-il un moyen d'améliorer et faire un seul appel à la variable pour correspondre à tous les "?" dans les: conditions?

grâce, P.

+0

Oui, mais le second extrait est plus optimisé comme u ne le font pas besoin de faire le calcul deux fois ... – khelll

+0

OK merci, mais y at-il un moyen de taper une seule fois "my_date" afin qu'il corresponde aux deux points d'interrogation dans les conditions? – Pierre

Répondre

1

J'utiliser named_scope. Dans le modèle ajouter:

named_scope :valid, 
      :conditions => 
      ["valid_from <= ? and valid_to >= ?", Date.today, Date.today] 

Et puis dans votre contrôleur, vous pouvez appeler:

@mymodels = Mymodel.valid 

Je pense qu'en mettant l'accent sur la réduction de deux appels à Date.today à un seul appel gaspille du temps. Cela ne rendra pas votre application plus rapide et n'utilisera pas moins de mémoire.

+0

J'accepte cette réponse pour le dernier bit: il y a peut-être un moyen, mais il n'y a aucun avantage particulier. Merci – Pierre

+1

Ceci est un problème avec l'utilisation de Date.today dans un named_scope. Cela est dû au fait que la portée names est compilée lorsque le modèle activerecord est compilé pour la première fois. Ainsi, l'appel à Date.today est évalué car il s'agit d'un appel de méthode lors de sa première découverte. Lors d'appels ultérieurs, cette valeur sera corrigée. Donc, c'est une bonne idée de prendre la valeur de la date comme une entrée. En savoir plus sur ce problème connu sur http://jitu-blog.blogspot.com/2009/07/looking-into-rails-namedscope.html – Sohan

1

Je ne suis pas au courant d'un moyen de faire ce que vous demandez, mais même si vous ne pouviez pas penser que cela vous achèterait beaucoup. Je voudrais créer un named scope dans votre classe de modèle.

Dans cet exemple, vous pouvez passer la date à la portée du nom, ou il sera par défaut à la date d'aujourd'hui, si aucune date est spécifiée:

named_scope :by_valid_date, lambda { |*args| 
      { :conditions => ["valid_from <= ? and valid_to >= ?", 
       (args.first || Date.today), (args.first || Date.today)]} } 
Questions connexes