Ruby-on-rails Rails:在 has_one 关联上创建
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3839779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails: create on has_one association
提问by Neko
Hi (huge Rails newbie here), I have the following models:
嗨(这里是一个巨大的 Rails 新手),我有以下模型:
class Shop < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
and
和
class User < ActiveRecord::Base
has_one :shop, :dependent => :destroy
end
When I'm about to create a new shop, I get the following error:
当我要创建一个新商店时,我收到以下错误:
private method `create' called for nil:NilClass
This is my controller:
这是我的控制器:
@user = current_user
@shop = @user.shop.create(params[:shop])
I've tried different variations by reading guides and tutorials here and there, but I'm more confused than before and can't get it to work. Any help would be greatly appreciated.
我在这里和那里阅读指南和教程,尝试了不同的变体,但我比以前更困惑,无法让它工作。任何帮助将不胜感激。
回答by nates
A more concise way to do this is with:
一个更简洁的方法是:
@user.create_shop(params[:shop])
See methods added by has_onein the Ruby on Rails guides.
请参阅Ruby on Rails 指南中由 has_one 添加的方法。
回答by sepp2k
First of all, here is how to do what you want:
首先,这里是如何做你想做的事:
@user = current_user
@shop = Shop.create(params[:shop])
@user.shop = @shop
Now here's why your version did not work:
现在这就是您的版本不起作用的原因:
You probably thought that this might work because if User had a has_manyrelation to Shop, @user.shops.create(params[:shop])wouldwork. However there is a big difference between has_manyrelations and has_onerelations:
您可能认为这可能会起作用,因为如果 Userhas_many与 Shop有关系,@user.shops.create(params[:shop])则会起作用。然而,has_many关系和has_one关系之间有很大的区别:
With a has_manyrelation, shopsreturns an ActiveRecord collection object, which has methods that you can use to add and remove shops to/from a user. One of those methods is create, which creates a new shop and adds it to the user.
通过has_many关系,shops返回一个 ActiveRecord 集合对象,该对象具有可用于向用户添加商店和从用户删除商店的方法。其中一种方法是create,它会创建一个新商店并将其添加给用户。
With a has_onerelation, you don't get back such a collection object, but simply the Shop object that belongs to the user - or nil if the user doesn't have a shop yet. Since neither Shop objects nor nil have a createmethod, you can't use createthis way with has_onerelations.
对于has_one关系,您不会取回这样的集合对象,而只会取回属于用户的 Shop 对象 - 如果用户还没有商店,则为 nil。由于 Shop 对象和 nil 都没有create方法,因此不能create对has_one关系使用这种方式。
回答by Fellow Stranger
Two more ways if you want saveinstead of create:
如果你想要save而不是另外两种方法create:
shop = @user.build_shop
shop.save
shop = Show.new
shop.user = @user
shop.save
回答by Rais
Just to add to above answers -
只是添加到上述答案 -
@user.create_shop(params[:shop])
Above syntax creates new record but it subsequently deletes similar existing record.
以上语法创建了新记录,但随后删除了类似的现有记录。
Alternatively, if you do not want to trigger delete callback
或者,如果您不想触发删除回调
Shop.create(user_id: user.id, title: 'Some unique title')
This threadmight be helpful. Click here

![Ruby-on-rails 如何修复 [unixODBC][Driver Manager] 未找到数据源名称且未指定默认驱动程序 (ODBC::Error)](/res/img/loading.gif)