Работа со сложными ассоциациями ActiveRecord

Я пытаюсь построить довольно сложные отношения. Как вы можете понять из приведенного ниже SQL, у меня есть три (четыре, если вы включаете User) модели в игре. Членство, группа и роль.

Пользователи принадлежат к группам через членство, которое само по себе может иметь роль. Таким образом, у пользователя есть роль в группе через членство.

Что я хочу сделать, так это ЗАКАЗАТЬ членство в определенной группе через роль, которую пользователь имеет в членстве. У ролей есть «ранг», связанный с ним. Итак, генеральный директор = 3, председатель отдела = 2, менеджер = 1, рабочий = 0 (например). Чтобы усложнить ситуацию, роль может быть подчинена другой роли. Таким образом, генеральный директор может быть частью роли, называемой советом директоров, а председатель отдела и менеджер могут быть частью роли, называемой высшим руководством (или что-то в этом роде).

Как вы можете видеть из моего SQL ниже, у меня все работает, мне просто нужно выяснить, как превратить это в ассоциацию ActiveRecord, чтобы, когда я нахожу группу, я мог сказать group.memberships, и это должно быть упорядочено в соответствии с к ролевому разряду.

SELECT `memberships`.* from `memberships`
 INNER JOIN `groups` ON `groups`.id = `memberships`.group_id
 INNER JOIN `roles` ON `memberships`.role_id = `roles`.id
 INNER JOIN `roles` `role_cat` ON `role_cat`.id = `roles`.type_id

WHERE `groups`.id = "HHC" AND `memberships`.expiration > CURDATE()
ORDER BY `role_cat`.rank DESC, `roles`.rank DESC

Ваше здоровье!


person Volte    schedule 08.07.2012    source источник


Ответы (2)


Если вы уверены, что запрос делает то, что вы хотите, вот самый простой способ получить из него отношение AR, учитывая, что у вас есть group, для которого вы хотите выполнить запрос:

group.memberships.joins(:role).
  joins('join roles as roles_cat on role_cat.id=roles.type_id').
  where("groups.id='HHC' and memberships.expiration>curdate()").
  order('role_cat.rank desc, roles.rank desc')
person HargrimmTheBleak    schedule 09.07.2012

Когда вы имеете дело со сложными запросами на соединение, я считаю, что лучше всего создать представление, представляющее модель соединения.

Сделав это, вы можете создать эту модель, если есть дополнительные свойства, к которым вам нужен доступ, и использовать has_many :join_model_name или, если вам просто нужно получить доступ к одной из объединенных моделей, вы можете использовать has_and_belongs_to_many :model_name

Конечно, можно многому научиться на собственном опыте за 6 месяцев :)

Спасибо Харгримм за помощь!

person Volte    schedule 07.03.2013