ruby on rails - rails - ¿Hay alguna manera de combinar ámbitos con nombre en un nuevo alcance con nombre?
ruby rails active record (6)
@ PJ : ya lo había considerado, pero lo descarté porque pensé que no sería capaz de encadenar más tarde un tercer ámbito con nombre, así:
Foo.ab(x, y).c(z)
Pero como ab(x, y)
devuelve lo que b(y)
devolvería, creo que la cadena funcionaría. ¡Forma de hacerme replantear lo obvio!
yo tengo
class Foo < ActiveRecord::Base
named_scope :a, lambda { |a| :conditions => { :a => a } }
named_scope :b, lambda { |b| :conditions => { :b => b } }
end
me gustaría
class Foo < ActiveRecord::Base
named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end
pero preferiría hacerlo de manera SECA. Puedo obtener el mismo efecto al usar
Foo.a(something).b(something_else)
pero no es particularmente encantador.
Al convertirlo en un método de clase, no podrá encadenarlo a un proxy de asociación, como:
@category.products.ab(x, y)
Una alternativa es aplicar este parche para habilitar una opción: through para named_scope:
named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
Al menos desde 3.2 hay una solución inteligente:
scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
Bueno, todavía soy nuevo en los rieles y no estoy seguro de a qué te refieres, pero si solo vas a reutilizar el código, ¿por qué no utilizar un método de clase normal?
def self.ab(a, b)
a(a).b(b)
end
Puede hacer que sea más flexible tomando * args en lugar de a y b, y luego posiblemente haga uno u otro opcional. Si está atrapado en named_scope, ¿no puede ampliarlo para hacer lo mismo?
Avíseme si estoy totalmente fuera de base con lo que quiere hacer.
Revisa:
http://github.com/binarylogic/searchlogic
¡Impresionante!
Ser especifico:
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
Sí Reutilizando named_scope para definir otro named_scope
Lo copio aquí para su conveniencia:
Puede usar proxy_options para reciclar un named_scope en otro:
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 esta manera se puede encadenar con otros named_scopes.
Utilizo esto en mi código y funciona perfectamente.
Espero que ayude.