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

Я имею

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)

но это не особенно мило.

6 ответов

Решение

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


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

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

Дай мне знать, если я совершенно не в курсе того, что ты хочешь сделать.

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

scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }

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

@category.products.ab(x, y)

Альтернативой является применение этого патча для включения опции:through для named_scope:

named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]

Да Повторное использование 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.

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

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

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

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

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

Проверять, выписываться:

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
Другие вопросы по тегам