Existe uma maneira de combinar os named scopes em um novo escopo nomeado?
-
09-06-2019 - |
Pergunta
Eu
class Foo < ActiveRecord::Base
named_scope :a, lambda { |a| :conditions => { :a => a } }
named_scope :b, lambda { |b| :conditions => { :b => b } }
end
Eu gostaria de
class Foo < ActiveRecord::Base
named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end
mas eu prefiro fazê-lo em um local SECO moda.Eu posso obter o mesmo efeito usando
Foo.a(something).b(something_else)
mas não é particularmente linda.
Solução
Bem, eu ainda sou novo para o rails e eu não tenho certeza exatamente o que está acontecendo por aqui, mas se você está indo só para a reutilização de código, por que não utilizar um método de classe?
def self.ab(a, b)
a(a).b(b)
end
Você poderia fazer o que mais flexíveis, levando *args, em vez de a e b e, em seguida, eventualmente, fazer um ou outro opcional.Se você está preso no named_scope, não se pode estendê-lo a fazer a mesma coisa?
Deixe-me saber se eu estou totalmente fora da base com o que você está querendo fazer.
Outras dicas
Pelo menos desde 3.2 existe uma solução inteligente :
scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
Tornando-o um método de classe, você não será capaz de cadeia para uma associação de proxy, como:
@category.products.ab(x, y)
Uma alternativa é a aplicação de este patch para activar a :a opção para named_scope:
named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
Sim Reutilização de named_scope para definir outra named_scope
Eu copiá-lo aqui para sua conveniência:
Você pode usar proxy_options para reciclar um named_scope em outro:
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
Desta forma, ela pode ser encadeado com outros named_scopes.
Eu uso isso no meu código e funciona perfeitamente.
Espero que ajude.
@PJ:você sabe, eu tinha considerado que, mas lhe negou provimento, porque eu pensei que eu não seria capaz de, mais tarde, em uma cadeia de terceira escopo nomeado, assim:
Foo.ab(x, y).c(z)
Mas desde que ab(x, y)
retorna tudo o que b(y)
iria voltar, eu acho que a cadeia seria o trabalho.E me fazer repensar o óbvio!
Confira:
http://github.com/binarylogic/searchlogic
Impressionante!
Para ser mais específico:
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