использование атрибутов модели соединения в рельсах has_many:through
-
18-09-2019 - |
Вопрос
например, у меня есть группа моделей и пользователь модели.
они связаны с :has_many, :through => groups_users
Таблица groups_users имеет атрибут moderator, указывающий, является ли пользователь модератором группы.
вопрос:как мне получить доступ ко всем модераторам данной группы?
после прочтения о :with_scope на ум приходит следующее
def find_moderators
Group.with_scope(:find=>{:conditions => "moderator=1"})
@moderators=@group.users
end
end
Однако после рельсов 2 with_scope становится защищенным и не разрешает данный код в контроллере, так какова хорошая альтернатива этому?
Решение
решено с
class Group
has_many :groups_users
has_many :moderatorships, :class_name => "GroupsUser",:conditions => {:moderator => true}
has_many :moderators, :through => :moderatorships, :class_name => "User", :source => :user
end
Предпочтительнее ответа Мэтта ван Хорна, потому что он создает только один запрос, когда мы выбираем информацию о пользователе с помощью @group.moderators, в то время как его решение дает отдельный запрос для каждого модератора.
редактировать:обновлено, чтобы ответить на вопрос Sizzlepants.модераторы, созданные с помощью этого кода, должны иметь атрибут модератора в модели соединения, установленный в значение true (rails использует :conditions при создании модели соединения), кроме того, если бы мне пришлось писать код сейчас, я бы назвал членство groups_users для удобства чтения.
Другие советы
class User
has_many :group_users
has_many :groups, :through => :groups_users
end
class GroupUser
belongs_to :user
belongs_to :group
named_scope :as_moderator, :conditions => "moderator=1"
end
class Group
has_many :group_users
has_many :groups, :through => :groups_users
def moderators
group_users.as_moderator.map{|gu|gu.user}
end
end
# use it:
@moderators = @group.moderators
or
@all_mods = Group.all.map{|g|g.moderators}.flatten
Обезьяний патч!
class Group < ActiveRecord::Base
public :with_scope
end