2016-03-25 2 views
0

у меня есть:Как я могу делегировать область? Рельсы

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 

EDIT:

Если я попробовать

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

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

Как я могу делегировать сферу?

+0

Привет Матрица, я обновил свой ответ, объясняя, почему вы, возможно, не хотите делать то, что вы пытаетесь сделать, и какой подход вам нужен для извлечения дочерних элементов с использованием родительской области. – Matt

+0

Должно быть, я недопонимаю вопрос, так как я уверен, что вы спрашиваете, что «слияние» - это решение. Удачи! – Matt

ответ

-1

Вы не можете легко делегировать области и не хотите, поскольку они будут возвращать объекты из целевого класса (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 

Edit: некоторые документы по этому признаку.

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

Редактировать снова:

Если вы действительно хотите, чтобы вернуть коллекцию UserItems из метода вы звоните по пункту, то вы можете сделать следующее:

class Item 
    class << self 
    delegate :equipped, to: :UserItem 
    end 
    ... 

Но это вернет UserItems в коллекции, а не в элементы. Что вызывает вопрос о том, почему делегировать это вообще? Если вам нужна коллекция предметов, и вы хотите ограничить эти предметы коллекцией оснащенных UserItems, используйте merge.

+0

Если я хочу использовать область действия в Item, я буду использовать: 'scope: equipped, -> {where (inventory_items: {equipped: true})}', но это не мой вопрос ^^ (я не делаю downvote) – Matrix

+0

@Matrix Область действия моего примера находится в модели «Элемент», она присоединяется к модели пользовательских элементов и использует область «оборудована» для ограничения возвращаемых «предметов» с помощью «user_items». Если я не буду полностью недопонимать ваш вопрос, это то, что вы хотите? По сути, это 'select items. * From items объединяет user_items, где user_items.equipped = true'. Вы хотите вернуть коллекцию объектов 'UserItem'? – Matt

+0

Нет, вы поняли вопрос, но в модели Item я могу добавить: 'scope: equipped, -> {where (user_items: {equipped: true})}' (заменить «inventory» на «user», его ошибка в мой последний ком), и все отлично. Но мой вопрос: как использовать scope в UserItem, чтобы не переопределять область в классе Item? – Matrix

Смежные вопросы