Rails has_one: через ассоциацию - PullRequest
62 голосов
/ 22 января 2010

Rails имеет ассоциацию has_one :through, которая помогает установить непосредственную связь с третьей моделью путем прохождения второй модели. Какая реальная польза от этого помимо создания ярлыка, в противном случае это был бы дополнительный шаг.

Взяв этот пример из руководства Rails :

class Supplier < ActiveRecord::Base
  has_one :account
  has_one :account_history, :through => :account
end

class Account < ActiveRecord::Base
  belongs_to :supplier
  has_one :account_history
end

class AccountHistory < ActiveRecord::Base
  belongs_to :account
end

может позволить нам сделать что-то вроде:

supplier.account_history

, который в противном случае был бы достигнут как:

supplier.account.history

Если это только для более простого доступа, то технически может существовать взаимно-однозначное сопоставление, связывающее модель с некоторой n-й моделью, проходящей через n-1 модели для более легкого доступа. Есть ли что-то еще, что я пропускаю, кроме ярлыка?

Ответы [ 3 ]

50 голосов
/ 22 января 2010
  1. Логика , хорошо, это может показаться немного слабым для этого, но было бы логично сказать, что «у меня есть поставщик, который имеет учетную запись со мной, я хочу просмотреть всю учетную запись» История этого поставщика ", поэтому для меня имеет смысл иметь доступ к истории счетов напрямую от поставщика.

  2. Эффективность , для меня это главная причина, по которой я бы использовал :through, просто потому, что это вызывает оператор соединения, а не вызов поставщика, а затем учетной записи и затем account_history. заметил количество обращений к базе данных?

    • с использованием :through, 1 вызов для получения поставщика, 1 вызов для получения account_history (rails автоматически использует :join для получения через аккаунт)

    • с использованием обычной связи, 1 звонок для получения поставщика, 1 звонок для получения учетной записи и 1 звонок для получения account_history

Я так думаю =) надеюсь, это поможет!

10 голосов
/ 09 сентября 2014

Я удивлен, что никто не коснулся Объектов ассоциации .

A has_many (или has_one) :through облегчает использование шаблона объекта ассоциации , когда у вас есть две вещи, связанные друг с другом, и само это отношение имеет атрибуты (то есть дату, когда была создана ассоциация или когда она истекает).

Это , который некоторые считают хорошей альтернативой has_and_belongs_to_many помощнику ActiveRecord. Причиной этого является то, что очень вероятно, что вам нужно будет изменить природу ассоциации или дополнить ее, и, когда вы участвуете в проекте пару месяцев, это может быть очень болезненным, если отношения изначально были установлены как a has_and_belongs_to_many (вторая ссылка уходит в некоторые подробности). Если он изначально настроен с использованием отношения has_many :through, то через пару месяцев в проекте можно легко переименовать модель соединения или добавить к ней атрибуты, чтобы разработчикам было проще реагировать на изменяющиеся требования. План изменений.

9 голосов
/ 02 апреля 2013
  • Обратная связь : рассмотрим классическую ситуацию user-members-group. Если пользователь может быть участником многих групп, то в группе много членов или пользователей, а у пользователя много групп. Но если пользователь может быть участником только в одной группе, группа по-прежнему имеет много участников: class User has_one :group, :through => :membership, но class Group has_many :members, :through => memberships. Промежуточная модель membership полезна для отслеживания обратной зависимости.

  • Расширяемость : отношение has_one :through может быть легко расширено и расширено до отношения has_many :through

...