Rails:在has_one关联上创建

时间:2010-10-01 13:49:12

标签: ruby-on-rails

嗨(巨大的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])

我通过阅读指南和教程尝试了不同的变化,但我比以前更困惑,无法让它工作。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:189)

更简洁的方法是:

@user.create_shop(params[:shop])

请参阅Ruby on Rails指南中的methods added by has_one

答案 1 :(得分:104)

首先,这是如何做你想要的:

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

现在这就是你的版本无效的原因:

您可能认为这可能有效,因为如果用户与商店有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关系。

答案 2 :(得分:7)

如果您想要save而不是create,还有两种方式:

shop = @user.build_shop
shop.save

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

答案 3 :(得分:0)

只需添加到以上答案-

@user.create_shop(params[:shop])

以上语法创建新记录,但随后删除相似的现有记录。

或者,如果您不想触发删除回调

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

thread可能会有所帮助。 Click here