Использование сборки с ассоциацией has_one в rails - PullRequest
134 голосов
/ 18 марта 2010

В этом примере я создаю user без profile, а затем создаю profile для этого пользователя.Я пытался использовать сборку с has_one ассоциацией, но это лопнуло.Единственный способ увидеть эту работу - использовать has_many.user должен иметь не более одного profile.

Я пробовал это.У меня есть:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

Но когда я делаю:

user.build_profile 

Я получаю ошибку:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4)  LIMIT 1

Есть ли способ в рельсах иметь 0 или1 ассоциация?

Ответы [ 4 ]

348 голосов
/ 19 марта 2010

Подпись метода build различна для ассоциаций has_one и has_many.

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

Синтаксис сборки для has_many ассоциации:

user.messages.build

Синтаксис сборки для has_one ассоциации:

user.build_profile  # this will work

user.profile.build  # this will throw error

Прочитайте has_one ассоциацию документацию для получения более подробной информации.

18 голосов
/ 19 марта 2010

Внимательно посмотрите на сообщение об ошибке. Это говорит о том, что у вас нет обязательного столбца user_id в таблице профиля . Установка отношений в модели - это только часть ответа.

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

Для получения дополнительной информации, пожалуйста, посмотрите на эту ссылку:

Основы ассоциации

0 голосов
/ 20 января 2017

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

old_profile = instance_method(:profile)
define_method(:profile) do
  old_profile.bind(self).call || build_profile
end

Теперь вызов метода #profile вернет связанный профиль или создаст новый экземпляр.

Источник: Когда вы исправляете метод, можете ли вы вызвать переопределенный метод из новой реализации?

0 голосов
/ 18 марта 2010

Это должно быть has_one. Если build не работает, вы можете просто использовать new:

ModelName.new( :owner => @owner )

совпадает с

@owner.model_names.build
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...