Est-il un moyen de combiner nommé étendues dans une nouvelle portée?
-
09-06-2019 - |
Question
J'ai
class Foo < ActiveRecord::Base
named_scope :a, lambda { |a| :conditions => { :a => a } }
named_scope :b, lambda { |b| :conditions => { :b => b } }
end
J'aimerais
class Foo < ActiveRecord::Base
named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end
mais je préfère le faire dans un endroit SEC de la mode.Je peux obtenir le même effet en utilisant des
Foo.a(something).b(something_else)
mais il n'est pas particulièrement belle.
La solution
Eh bien, je suis encore nouveau pour rails et je ne suis pas sûr exactement ce que vous allez ici, mais si vous êtes juste de réutilisation de code, pourquoi ne pas utiliser une classe ordinaire de la méthode?
def self.ab(a, b)
a(a).b(b)
end
Vous pourriez faire plus souples en prenant *args au lieu de a et b, et puis, éventuellement, faire l'un ou l'autre option.Si vous êtes coincé sur named_scope, ne pouvez-vous pas l'étendre à en faire de même?
Permettez-moi de savoir si je suis totalement à côté de la plaque avec ce que vous êtes désireux de le faire.
Autres conseils
Au moins depuis la 3.2 il y a une solution intelligente :
scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
En faisant de cela une méthode de classe, vous ne serez pas en mesure de chaîne à une association de proxy, comme:
@category.products.ab(x, y)
Une alternative est l'application de ce patch pour permettre à un :grâce à l'option pour named_scope:
named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
Oui La réutilisation named_scope pour définir un autre named_scope
Je copie ici pour votre commodité:
Vous pouvez utiliser proxy_options recycler un named_scope dans une autre:
class Thing
#...
named_scope :billable_by, lambda{|user| {:conditions => {:billable_id => user.id } } }
named_scope :billable_by_tom, lambda{ self.billable_by(User.find_by_name('Tom').id).proxy_options }
#...
end
De cette manière, il peut être enchaîné avec d'autres named_scopes.
- Je l'utiliser dans mon code et il fonctionne parfaitement.
J'espère que cela aide.
@PJ:vous savez, j'ai considéré que, mais il a rejeté parce que je pensais que je ne serais pas capable plus tard de la chaîne sur un troisième nommé portée, comme suit:
Foo.ab(x, y).c(z)
Mais depuis ab(x, y)
renvoie ce que b(y)
serait de retour, je pense que la chaîne de travail.Façon de me faire repenser à ce qui est évident!
Découvrez:
http://github.com/binarylogic/searchlogic
Impressionnant!
Pour être précis:
class Foo < ActiveRecord::Base
#named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
# alias_scope, returns a Scope defined procedurally
alias_scope :ab, lambda {
Foo.a.b
}
end