Rails:在has_one关联上创建

Nek*_*eko 93 ruby-on-rails

嗨(巨大的Rails新手在这里),我有以下型号:

class Shop < ActiveRecord::Base
  belongs_to :user
  validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
Run Code Online (Sandbox Code Playgroud)

class User < ActiveRecord::Base
  has_one :shop, :dependent => :destroy
end
Run Code Online (Sandbox Code Playgroud)

当我即将创建一个新商店时,我收到以下错误:

private method `create' called for nil:NilClass
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

@user = current_user
@shop = @user.shop.create(params[:shop])
Run Code Online (Sandbox Code Playgroud)

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

nat*_*tes 198

更简洁的方法是:

@user.create_shop(params[:shop])
Run Code Online (Sandbox Code Playgroud)

请参阅Ruby on Rails指南中由has_one添加的方法.

  • 请注意,如果您不止一次create_shop,它将删除以前的商店.例如,如果你运行`@user.create_shop(params [:shop_one_info])`它将创建shop_one,但是如果你运行`@user.create_shop(params [:shop_two_info]),它将删除第一个商店并创建第二个. (6认同)
  • 这绝对是更好的方法 (5认同)

sep*_*p2k 115

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

@user = current_user
@shop = Shop.create(params[:shop])
@user.shop = @shop
Run Code Online (Sandbox Code Playgroud)

现在这就是你的版本不起作用的原因:

你可能认为这可能有用,因为如果User has_many与Shop 有关系,@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添加的方法](http://guides.rubyonrails.org/association_basics.html#methods-added-by-has_one). (106认同)

Fel*_*ger 7

如果你想要的话还有两种方法,save而不是create:

shop = @user.build_shop
shop.save

shop = Show.new
shop.user = @user
shop.save
Run Code Online (Sandbox Code Playgroud)