Указание внешнего ключа в отношении has_many: through - PullRequest
6 голосов
/ 18 января 2010

У меня есть следующие три модели: Пользователь, Проект и Назначение.

Пользователь has_many Проецирует через назначение.Тем не менее, присвоение фактически имеет два внешних ключа, которые относятся к пользователю: user_id (представляет пользователя, которому был назначен проект) и completer_id (представляет пользователя, который завершил проект).

Часто user_id и completer_id будут одинаковыми (если пользователь, которому был назначен проект, завершит его).Однако, если другой пользователь завершит его, user_id и completeter_id будут другими.

В моей модели User у меня есть следующее:

class User < ActiveRecord::Base
  has_many   :assignments
  has_many   :incomplete_assignments, :class_name => 'Assignment',
    :conditions  => 'completer_id IS NULL'
  has_many   :completed_assignments, :class_name => 'Assignment',
    :foreign_key => 'completer_id'

  # this is the important one
  has_many   :incomplete_projects,
    :through     => :assignments,
    :source      => :project,
    :conditions  => 'completer_id IS NULL'
end

Я хотел бы создать другую ассоциацию, называемую :completed_projects, который использует completer_id в качестве внешнего ключа для пользователя в модели :through, а не :user_id.Возможно ли это сделать?

И, кроме того, я знаю о опции :foreign_key.Однако этот параметр игнорируется при использовании :through, поэтому я хотел бы знать, есть ли способ сделать это без него.

Наконец, я должен упомянуть, что я открыт для других проектов, еслиэто не может быть сделано таким образом, и кто-то может придумать лучший способ.

Ответы [ 2 ]

3 голосов
/ 18 января 2010

Вы всегда можете использовать SQL для выбора, если ActiveRecord не может легко выразить связь из коробки:

has_many :completed_projects,
:class_name => "Project",
:finder_sql => 'SELECT p.* FROM projects p ' +
  'INNER JOIN assignments a ON p.id=a.project_id ' +
  'INNER JOIN users u on u.id=a.completer_id ' +
  'WHERE u.id=#{id}'
2 голосов
/ 18 января 2010

Есть ли у вас другие метаданные в вашей таблице назначений?

Если бы не я, я бы просто использовал habtm и добавил вместо этого завершающий_ид в таблицу проектов, в любом случае имеет смысл жить там.

Если вам нужно / вы хотите использовать has_many: через вы можете посмотреть на использование named_scopes (с учетом версии Rails), чтобы вы могли сказать user.projects.completed и user.projects.incomplete

...