Я столкнулся с чем-то, что не понимаю, как моделировать с помощью ассоциаций Rails, и ни STI, ни полиморфизм, похоже, не решают эту проблему.
Я хочу иметь возможность доступа к атрибутам из таблицы соединений через коллекцию, созданную has_many: through.
В приведенном ниже коде это означает, что я хочу иметь возможность получить доступ к названию и описанию позиции комитета через объекты в коллекции .members, но, насколько я вижу, я не могу этого сделать. Я должен пройти через оригинальную таблицу соединений.
например. моделирование клуба и членов его комитета
class User < ActiveRecord::Base
attr_accessible :full_name,
:email
has_many: committee_positions
has_many: committees, :through => committee_positions
end
class Committee < ActiveRecord::Base
attr_accessible :name
has_many :committee_positions
has_many :members, :through => :committee_positions
end
class CommitteePosition < ActiveRecord::Base
attr_accessible :user_id,
:committee_id,
:member_description,
:role_title
belongs_to :committee
belongs_to :user
end
Предположим, что каждый экземпляр позиции комитета имеет уникальное описание
то есть описание относится как к члену, так и к комитету, и поэтому должно храниться в таблице соединений, а не вместе с пользователем или клубом.
, например
Committee member: Matt Wilkins
Role: "Rowing club president"
Description: "Beats the heart of the rowing club to his own particular drum"
Есть ли способ получить доступ к данным в таблице соединений через коллекцию Committee.members?
Хотя активная запись дает нам этот отличный псевдоним для непосредственного обращения к участникам, похоже, нет никакого способа получить доступ к данным в объединительной таблице, которая создала коллекцию:
Я не могу сделать следующее:
rowing_committee.members.find_by_role_title('president').name
Каждый элемент в коллекции .members является объектом пользователя и, похоже, не имеет доступа ни к роли, ни к описанию, которое хранится в таблице присоединения CommitteePositions.
Единственный способ сделать это будет:
rowing_committee.committee_positions.find_by_role_title('president').user.name
Это прекрасно выполнимо, но неуклюже и бесполезно. Я чувствую, что сценарий использования достаточно общий, что я вполне могу что-то упустить.
К чему бы я хотел получить доступ через объекты в коллекции Committee.members
member
- full_name
- email
- role_title (referenced from join table attributes)
- member_description (referenced from join table attributes)
Это всего лишь маленькая вещь, но она кажется ужасной. Есть ли простой способ указать объектам-членам наследовать информацию, содержащуюся в таблице соединений?
-------------- приложение
Работая над этим, я понимаю, что могу на полпути к решению проблемы, просто определив новый класс для члена комитета и ссылаясь на него вместо пользователя в отношении has_many: through. Это работает немного лучше, но все еще довольно неуклюже
class Committee < ActiveRecord::Base
...
has_many :committee_positions
has_many :members,
:through => :committee_positions,
:class_name => 'CommitteeMember'
...
end
class CommitteeMember < User
def description( committee )
self.committees.find_by_committee_id( committee.id ).description
end
def role( committee )
self.committees.find_by_committee_id( committee.id ).description
end
end
Теперь это становится ближе, но все еще кажется неуклюжим в том смысле, что код для его использования будет:
committee = Committee.first
president_description = committee.members.find_by_title('president').description( committee )
Есть ли способ инициализировать эти объекты комитетом, на который они ссылаются?