Есть ли способ объединить именованные области в новую именованную область?

у меня есть

class Foo < ActiveRecord::Base
  named_scope :a, lambda { |a| :conditions => { :a => a } }
  named_scope :b, lambda { |b| :conditions => { :b => b } }
end

Я хотел бы

class Foo < ActiveRecord::Base
  named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } }
end

но я бы предпочел сделать это СУХИМ способом. Я могу получить тот же эффект, используя

 Foo.a(something).b(something_else)

но это не особенно прекрасно.


person James A. Rosen    schedule 26.08.2008    source источник
comment
кажется, что это поведение не является стандартным в рельсах.   -  person troelskn    schedule 12.08.2010


Ответы (6)


Ну, я все еще новичок в рельсах, и я не совсем уверен, что вы здесь собираетесь делать, но если вы просто собираетесь повторно использовать код, почему бы не использовать обычный метод класса?


        def self.ab(a, b)
            a(a).b(b)
        end
    

Вы можете сделать это более гибким, взяв *args вместо a и b, а затем, возможно, сделать один или другой необязательным. Если вы застряли на named_scope, не могли бы вы расширить его, чтобы делать то же самое?

Дайте мне знать, если я полностью не согласен с тем, что вы хотите сделать.

person PJ.    schedule 27.08.2008
comment
С этим решением он не будет вести себя как обычная область. Например, его не будет в Model.scopes. - person KARASZI István; 17.02.2011

По крайней мере, с версии 3.2 есть умное решение:

scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
person Meta Lambda    schedule 29.05.2015

Сделав его методом класса, вы не сможете связать его с прокси-сервером ассоциации, например:

@category.products.ab(x, y)

В качестве альтернативы можно применить этот патч, чтобы включить опция :through для named_scope:

named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
person Community    schedule 11.05.2009

Да Повторное использование named_scope для определения другого named_scope

Копирую сюда для вашего удобства:

Вы можете использовать proxy_options для преобразования одной named_scope в другую:

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

Таким образом, его можно связать с другими named_scopes.

Я использую это в своем коде, и он отлично работает.

Я надеюсь, что это помогает.

person Oinak    schedule 20.07.2010
comment
Предостережение заключается в том, что proxy_options возвращает только область последней именованной области, поэтому это нельзя сделать для другой производной именованной области. - person aceofspades; 09.09.2010

@PJ: вы знаете, я думал об этом, но отклонил его, потому что я думал, что не смогу позже сцепить третью именованную область, например так:

Foo.ab(x, y).c(z)

Но поскольку ab(x, y) возвращает то же, что и b(y), я думаю, что цепочка будет работать. Способ заставить меня переосмыслить очевидное!

person James A. Rosen    schedule 27.08.2008

Проверить:

http://github.com/binarylogic/searchlogic

Впечатляющий!

Чтобы быть конкретным:

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
person aceofspades    schedule 08.09.2010