Rails ассоциации с одинаковыми моделями - PullRequest
4 голосов
/ 09 апреля 2009

У меня есть два класса со следующими ассоциациями:

class Incident
  has_one :assignee
  has_one :technician

class User 
  has_many :incidents

Обратите внимание, что поля уполномоченного и техника относятся к объектам типа Пользователь Как эти отношения должны быть в модели?

Ответы [ 2 ]

9 голосов
/ 09 апреля 2009

Предположительно, Инцидент должен принадлежать уполномоченному и техническому специалисту, поскольку внешний ключ, содержащий эти отношения, будет в таблице инцидентов, а не в таблице сотрудников

class Incident
  belongs_to :assignee, :class_name => 'User'
  belongs_to :technician, :class_name => 'User'

class User 
  has_many :assigned_incidents, :class_name => 'Incident', :foreign_key => 'assignee_id'

  # not sure the wording you'd want to use for this relationship
  has_many :technician_incidents, :class_name => 'Incident', :foreign_key => 'technician_id'

Вы бы хотели, чтобы поля внешнего ключа были incidents.assignee_id, incidents.technician_id

1 голос
/ 24 апреля 2012

Вот полный ответ на этот вопрос, на случай, если людям, посещающим этот вопрос, будет трудно собрать все воедино (как я это делал, когда впервые это изучил).

Некоторые части ответа имеют место в ваших Миграциях, а некоторые в ваших Моделях:

Миграции

class CreateIncidents < ActiveRecord::Migration
  create_table :incidents do |t|
    def up
      t.references :assignee
      t.references :technician
    end
  end
end

Здесь вы указываете, что в этой таблице есть два столбца, которые будут называться: assignee и: technician и которые содержат ссылки на другую таблицу. Rails фактически создаст для вас столбцы с именем assignee_id и technician_id. В нашем случае они будут ссылаться на строки в таблице Users, но мы указываем это в моделях, а не в миграциях.

Модель

class Incident < ActiveRecord::Base
  belongs_to :assignee, class_name => 'User'
  belongs_to :technician, class_name => 'User'
end

Здесь вы создаете свойство в модели инцидентов с именем: assignee, затем указываете, что это свойство будет ссылаться на экземпляр класса User. Rails, увидев «own_to», будет искать в вашей базе данных столбец assignee_id, который мы определили выше, и использовать его для хранения внешнего ключа. Тогда вы делаете то же самое для техника.

Это позволит вам получить доступ к вашему правопреемнику и техническому специалисту, оба экземпляра модели User, через экземпляр модели Incident, например:

Incident.assignee.name
Incident.technician.email

Вот ваша модель пользователя:

class User < ActiveRecord::Base
  has_many :assigned_incidents, :class_name => 'Incident', :foreign_key => 'assignee_id'
  has_many :incidents_as_technician, :class_name => 'Incident', :foreign_key => 'technician_id'
end

Здесь вы создаете свойство в пользовательской модели с именем: assign_incidents, определяя, что это свойство будет ссылаться на экземпляры модели инцидентов и что внешний ключ в модели инцидентов, который ссылается на эту модель пользователя, нам нужен использовать для этого свойства называется 'assignee_id'. Затем вы делаете то же самое для incidents_as_technician (это наименование кажется неуклюжим, но без лучшего знания того, что вы пытаетесь сделать, у меня нет особых предложений).

Это позволяет вам получить все назначенные пользователю инциденты или инциденты в качестве технического специалиста, выполнив следующее:

User.assigned_incidents
User.incidents_as_technician

Выполнение любого из них вернет массив экземпляров модели Incident.

...