Подтвердить что ты не робот

Rails: создать связь has_one

Привет (огромный Rails новичок здесь), у меня есть следующие модели:

class Shop < ActiveRecord::Base
  belongs_to :user
  validates_uniqueness_of :title, :user_id, :message => "is already being used"
end

и

class User < ActiveRecord::Base
  has_one :shop, :dependent => :destroy
end

Когда я собираюсь создать новый магазин, я получаю следующую ошибку:

private method `create' called for nil:NilClass

Это мой контроллер:

@user = current_user
@shop = @user.shop.create(params[:shop])

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

4b9b3361

Ответ 1

Прежде всего, вот как сделать то, что вы хотите:

@user = current_user
@shop = Shop.create(params[:shop])
@user.shop = @shop

Теперь, почему ваша версия не работает:

Вероятно, вы считали, что это может сработать, потому что если бы у Пользователя было отношение has_many к Shop, @user.shops.create(params[:shop]) работало бы. Однако существует большая разница между отношениями has_many и has_one:

С отношением has_many shops возвращает объект коллекции ActiveRecord, в котором есть методы, которые вы можете использовать для добавления и удаления магазинов/от пользователя. Один из этих методов - create, который создает новый магазин и добавляет его пользователю.

С отношением has_one вы не возвращаете такой объект коллекции, а просто объект Shop, принадлежащий пользователю, или nil, если пользователь еще не имеет магазина. Поскольку ни объекты Shop, ни nil не имеют метода create, вы не можете использовать create таким образом с отношениями has_one.

Ответ 3

Еще два способа, если вы хотите save вместо create:

shop = @user.build_shop
shop.save

shop = Show.new
shop.user = @user
shop.save

Ответ 4

Просто чтобы добавить к ответам выше -

@user.create_shop(params[:shop])

Выше синтаксис создает новую запись, но впоследствии удаляет аналогичную существующую запись.

В качестве альтернативы, если вы не хотите инициировать удаление обратного вызова

Shop.create(user_id: user.id, title: 'Some unique title')

Эта тема может быть полезной. кликните сюда