Вопрос

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

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

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

В моей пользовательской модели у меня есть следующее:

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, поэтому я хотел бы знать, есть ли способ сделать это без этого.

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

Это было полезно?

Решение

Вы всегда можете использовать 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}'

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top