如何委托范围?栏杆

Mat*_*rix 3 delegates scope ruby-on-rails ruby-on-rails-4

我有 :

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
Run Code Online (Sandbox Code Playgroud)

编辑:

如果我尝试

User.first.items.equipped => undefined method 'equipped' for #<ActiveRecord::Associations::CollectionProxy []>

User.first.items.armor.equipped => undefined method 'equipped' for #<ActiveRecord::AssociationRelation []>

如何委托范围?

Mat*_*att 8

您不能轻松地委托给作用域,也不想这样做,因为它将返回目标类(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
Run Code Online (Sandbox Code Playgroud)

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

将跨模型的命名范围与ActiveRecord#Merge一起使用 http://apidock.com/rails/ActiveRecord/SpawnMethods/merge

再次编辑:

如果您真的想从调用Item的方法中返回UserItems的集合,则可以执行以下操作:

class Item
  class << self
    delegate :equipped, to: :UserItem
  end 
  ...
Run Code Online (Sandbox Code Playgroud)

但这将在集合中返回UserItems,而不是Items。哪个提出了为什么要完全委托这个问题?如果您想要一个Item的集合,并且想要通过装备精良的UserItems的集合来限制这些项目,请使用merge