Привет (огромный новичок в 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])
Я пробовал разные варианты, читая руководства и учебные пособия здесь и там, но я больше запутался, чем раньше, и не могу заставить его работать. Любая помощь будет принята с благодарностью.
ruby-on-rails
Неко
источник
источник
@user.build_shop(params)
Ответы:
Прежде всего, вот как делать то, что вы хотите:
Вот почему ваша версия не сработала:
Вы, наверное, думали, что это может сработать, потому что, если бы Пользователь имел
has_many
отношение к Магазину,@user.shops.create(params[:shop])
это сработало бы . Однако междуhas_many
отношениями иhas_one
отношениями есть большая разница :С
has_many
отношениемshops
возвращает объект коллекции ActiveRecord, у которого есть методы, которые вы можете использовать для добавления и удаления магазинов для пользователя. Один из таких методов -create
создать новый магазин и добавить его пользователю.С помощью
has_one
отношения вы не получаете обратно такой объект коллекции, а просто объект Shop, принадлежащий пользователю - или ноль, если у пользователя еще нет магазина. Поскольку ни объекты Shop, ни nil не имеютcreate
метода, вы не можете использоватьcreate
этот способ сhas_one
отношениями.источник
@user.create_shop(params[:shop])
. См. Методы, добавленные has_one .Более краткий способ сделать это:
См. Методы, добавленные has_one, в руководствах по Ruby on Rails.
источник
@user.create_shop(params[:shop_one_info])
он создаст shop_one, НО, если вы запустите@user.create_shop(params[:shop_two_info])
, он удалит первый магазин и создаст второй.@user.build_shop(params)
Еще два способа, если вы хотите
save
вместоcreate
:источник
Просто чтобы добавить к приведенным выше ответам -
Приведенный выше синтаксис создает новую запись, но впоследствии удаляет аналогичную существующую запись.
В качестве альтернативы, если вы не хотите запускать обратный вызов удаления
Эта ветка может быть полезна. кликните сюда
источник