在现有范围Activerecord中使用另一个类作用域

时间:2014-07-08 14:08:51

标签: ruby-on-rails ruby activerecord

我想在第一个类的范围内使用另一个类的范围

所以而不是

scope :active, -> {includes(:b).where(b: {column: 'ACTIVE'}).where(a: {column2: 'ACTIVE'})}

我希望能够使用b

的范围
scope :active, -> {includes(b.active).where(a: {column2: 'Active'})}

2 个答案:

答案 0 :(得分:1)

您可以使用merge执行此操作:

scope :active, -> { includes(:b).merge(B.active)
                                .where(a: {column2: 'Active'}) }

注意:我使用B来表示b列或对象的模型类。

或者,假设您已经进入a模型:

scope :active, -> { includes(:b).merge(B.active)
                                .where(column2: 'Active') }

此外,如果您想要加载,那么使用includes非常棒。否则,使用joins会更快,更少开销,如下所示:

scope :active, -> { joins(:b).merge(B.active)
                             .where(column2: 'Active') }

答案 1 :(得分:-1)

我建议在模型上使用范围,如果它是特定于管理员的,那么可以将其分开关注 http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

module AdminUserScopes
  extend ActiveSupport::Concern

  included do
    scope :admin_scope1, -> { includes(:b).where(b: {column: 'ACTIVE'}).where(a: {column2: 'ACTIVE'}) }
    scope :admin_scope2, -> { admin_scope1.where(a: {column2: 'Active'}) }
  end
end

# in your model

include AdminUserScopes

# in active_admin

scope :active, -> { admin_scope1 }
scope :active2, -> { admin_scope2 }

UPD:

如果您想将一个条件用于其他模型,则可以使用merge

Dog.all.merge(User.males) # => select * from dogs where sex = 1;

如果要在关联过滤中使用,则:

Post.where(user: User.males) # => select * from posts where user_id in (select users.id from users where sex = 1)

在您的情况下,我猜您有AB,并且您希望获得与活动B记录相关的活动A记录

# in A
scope :active, -> { where(column: 'ACTIVE') }

# in B
scope :active, -> { where(column2: 'ACTIVE', a: A.active) }

# in somewhere else
scope :active, -> { where(a: A.active) } # => have active A which have active B

P.S。通过更多信息丰富的名字,它会变得更容易,并且#34; A""和" B""很难:))