рельсы has_one через коллекцию - PullRequest
4 голосов
/ 25 июня 2011

Я начну с вставки соответствующего кода, а затем объясню позже, что я пытаюсь сделать

class User < ActiveRecord::Base
  has_many :compus, :dependent => :destroy
  has_many :companies, :through => :compus
end

class Company < ActiveRecord::Base
  has_many :compus, :dependent => :destroy
  has_many :employees, :through => :compus, :source => :user
  has_one  :owner, :through => :compus, :source => :user, :conditions => { :owner => true }
end

class Compu < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

В таблице compus есть следующие столбцы (скопированные из миграции)

create_table :compus do |t|
  t.references :company
  t.references :user
  t.string     :job_title
  t.boolean    :owner, null: false, default: false

  t.timestamps
end

Итак, как вы можете видеть, у меня есть пользователь, который может создавать n компаний и работать в n компаниях, а работа в компании не означает, что он является владельцем ..

Я бы хотел получить:

user.companies # => Компании, которые пользователь создал или имеет рабочие места (я беспокоюсь о фильтрации результатов позже)

company.employees # => Все пользователи, которые работают в этой компании (через compus)

company.owner # => Один пользователь, который изначально создал компанию (или другой, если он был перенесен позже)

Поэтому я добавил следующую спецификацию, прежде чем написал код выше.

it "has one owner" do
  company = Factory(:company)
  user    = Factory(:user)

  company.should respond_to(:owner)

  user.companies << company

  company.owner.should === user
end

но я получаю следующую ошибку:

ActiveRecord::HasOneThroughCantAssociateThroughCollection:
       Cannot have a has_one :through association 'Company#owner' where the :through association 'Company#compus' is a collection. Specify a has_one or belongs_to association in the :through option instead.

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

Еще один вопрос, пока я на нем: как я могу легко получить доступ к: job_title, который находится в таблице compus, через ассоциацию?

1 Ответ

7 голосов
/ 25 июня 2011

Вы можете просто сделать функцию возврата владельца

def owner
    compus.where(:owner => true).first
end

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

...