我有 :

class UserItem < ActiveRecord::Base

  belongs_to :user
  belongs_to :item

  scope :equipped, -> { where(equipped: true) }
end

class Item < ActiveRecord::Base
   has_many :user_items
   has_many :users, through: :user_items

   scope :armor, -> { where(type: 'Armor') }
   delegate :equipped, to: :user_items

end

编辑:

如果我尝试
User.first.items.equipped => undefined method 'equipped' for #<ActiveRecord::Associations::CollectionProxy []>User.first.items.armor.equipped => undefined method 'equipped' for #<ActiveRecord::AssociationRelation []>
我如何委派给范围?

最佳答案

您不能轻松地委托(delegate)给作用域,也不想委托(delegate),因为它会从目标类 (UserItem) 返回对象,而不是子类。

相反,您可以非常简单地合并范围:

class UserItem < ActiveRecord::Base
  scope :equipped, -> { where(equipped: true) }
end

class Item < ActiveRecord::Base
  scope :equipped, -> {joins(:user_items).merge(UserItem.equipped)}
end

=> Item.equipped
=> collection of items for which they have a user_item association that is equipped

编辑:有关此功能的一些文档。

Using Named Scopes Across Models with ActiveRecord#Merge
http://apidock.com/rails/ActiveRecord/SpawnMethods/merge

再次编辑:

如果您真的想从对 Item 调用的方法返回 UserItems 的集合,则可以执行以下操作:
class Item
  class << self
    delegate :equipped, to: :UserItem
  end
  ...

但这将返回集合中的 UserItems,而不是 Items。这就引出了一个问题,为什么要委托(delegate)这个?
如果您想要一个 Items 集合,并且您想通过一组配备的 UserItems 来限制这些项目,那么使用 merge

10-07 18:22