Rails has_many: through и has_one: through ассоциации - PullRequest
2 голосов
/ 22 июня 2011

Сначала я использую Rails 3.1 из ветки 3-1-stable , обновленной час назад.

Я разрабатываю приложение, в котором у меня есть3 основные модели Пользователь , Компания и Работа , вот соответствующая часть моделей:

class User < ActiveRecord::Base
  has_many :companies_users, class_name: "CompaniesUsers"
  has_many :companies, :through => :companies_users, :source => :company
end

class Company < ActiveRecord::Base
  has_many :companies_users, class_name: "CompaniesUsers"
  has_many :employees, :through => :companies_users, :source => :user
  has_many :jobs, :dependent => :destroy
end

class Job < ActiveRecord::Base
  belongs_to :company, :counter_cache => true
end

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

Код работает просто отлично,но мне было интересно, возможно ли:

Я хочу связать работу с работодателем , так что подумайте об этом сценарии: Пользователь Джон кто является сотрудником Пример , он опубликовал работу Rails Developer, поэтому я хочу получить доступ к @job.employer, и он должен вернуть меня к пользователю Джон , другими словами:

@user = User.find_by_name('john')
@job   = Job.find(1)
@job.employer == @user       #=> true

Итак, я подумал о двух возможных решениях

Первое решение

class Job
  has_one :employer, :through => :employers
end

class User
  has_many :jobs, :through => :employers
end

class Employer
  belongs_to :job
  belongs_to :user
end

Второе решение

class Job
  has_one :employer, :class_name => "User"
end

class User
  belongs_to :job
end

По какому маршруту мне идти?Правильный ли мой код?

У меня есть еще вопрос, как избавиться от опции class_name => "CompaniesUsers", переданной has_many, должен ли класс быть Singular или Plural?Должен ли я переименовать его в что-то вроде Сотрудники ?

PS: я отправил тот же вопрос в Ruby on Rails: Talk

Ответы [ 2 ]

1 голос
/ 22 июня 2011

Если я что-то упустил, я бы предложил просто сделать

class Job
  belongs_to :employer, :class_name => "User"
end

class User
  has_many :jobs
end

Это даст вам такие методы, как

user = User.first
user.jobs.create(params)
user.jobs # array
job = user.jobs.first
job.employer == user # true

Вам понадобится целое поле employer_id в вашей таблице заданий, чтобы это работало.

0 голосов
/ 04 марта 2013

Как правило, вы хотите назвать свою модель доступа:

company_user

Тогда вам это не нужно:

class_name: "CompaniesUsers"

Просто убедитесь, что имя вашей таблицы базы данных:

company_users

То, что у вас есть, работает на вас, так что это здорово.Я просто нахожу, что когда я не следую условностям, я сталкиваюсь с неприятностями в будущем.

...