Esiste un modo per combinare gli ambiti denominati in un nuovo ambito denominato?
-
09-06-2019 - |
Domanda
Io ho
class Foo < ActiveRecord::Base
named_scope :a, lambda { |a| :conditions => { :a => a } }
named_scope :b, lambda { |b| :conditions => { :b => b } }
end
Mi piacerebbe
class Foo < ActiveRecord::Base
named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end
ma preferirei farlo in modo ASCIUTTO.Posso ottenere lo stesso effetto usando
Foo.a(something).b(something_else)
ma non è particolarmente bello.
Soluzione
Beh, sono ancora nuovo nei binari e non sono sicuro esattamente di cosa stai cercando qui, ma se stai solo cercando il riutilizzo del codice, perché non utilizzare un metodo di classe normale?
def self.ab(a, b)
a(a).b(b)
end
Potresti renderlo più flessibile prendendo *args invece di aeb, e quindi eventualmente rendere l'uno o l'altro facoltativo.Se sei bloccato su name_scope, non puoi estenderlo per fare più o meno la stessa cosa?
Fammi sapere se sono completamente fuori strada rispetto a quello che vuoi fare.
Altri suggerimenti
Almeno dalla 3.2 esiste una soluzione intelligente:
scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
Rendendolo un metodo di classe non sarai in grado di concatenarlo a un proxy di associazione, come:
@category.products.ab(x, y)
Si sta applicando un'alternativa questa toppa per abilitare un'opzione :through per name_scope:
named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
SÌ Riutilizzo di name_scope per definire un altro name_scope
Lo copio qui per tua comodità:
Puoi utilizzare proxy_options per riciclare un name_scope in un altro:
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
In questo modo può essere concatenato con altri name_scope.
Lo uso nel mio codice e funziona perfettamente.
Spero possa essere d'aiuto.
@PJ:sai, ci avevo pensato, ma l'ho scartato perché pensavo che non sarei stato in grado di concatenare in seguito a terzo ambito denominato, in questo modo:
Foo.ab(x, y).c(z)
Ma da allora ab(x, y)
restituisce qualunque cosa b(y)
ritornerei, penso che la catena funzionerebbe.Un modo per farmi riconsiderare l'ovvio!
Guardare:
http://github.com/binarylogic/searchlogic
Degno di nota!
Essere specifici:
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