Ruby on rails Rails:create on有一个关联

Ruby on rails Rails:create on有一个关联,ruby-on-rails,Ruby On Rails,嗨(这里是Rails新手),我有以下型号: class Shop < ActiveRecord::Base belongs_to :user validates_uniqueness_of :title, :user_id, :message => "is already being used" end 这是我的控制器: @user = current_user @shop = @user.shop.create(params[:shop]) 我在这里和那里阅读指南和教程

嗨(这里是Rails新手),我有以下型号:

class Shop < ActiveRecord::Base
  belongs_to :user
  validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
这是我的控制器:

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

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

首先,以下是如何实现您的愿望:

@user = current_user
@shop = Shop.create(params[:shop])
@user.shop = @shop
现在,以下是您的版本不起作用的原因:

您可能认为这可能会起作用,因为如果用户与Shop有很多关系,
@User.shops.create(params[:Shop])
会起作用。然而,
有许多关系和
有一个关系之间有很大的区别:

使用
has\u many
关系,
shops
返回一个ActiveRecord集合对象,该对象具有可用于向用户添加或从用户中删除商店的方法。其中一种方法是
create
,它创建一个新商店并将其添加到用户


使用
has_one
关系,您不会返回这样的集合对象,而只是返回属于用户的商店对象,如果用户还没有商店,则返回零。由于Shop objects和nil都没有
创建
方法,因此不能将
创建
这种方法用于
具有一个
关系。

更简洁的方法是:

@user.create_shop(params[:shop])

请参阅RubyonRails指南中的。

如果您希望
保存
而不是
创建
,还有两种方法:

shop = @user.build_shop
shop.save

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

只是为了补充上述答案-

@user.create_shop(params[:shop])
上述语法创建新记录,但随后删除类似的现有记录

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

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

这可能会有帮助

谢谢你的回答,sepp2k。我现在明白了为什么我的代码不能工作了。你也可以使用
@user.create\u shop(params[:shop])
。请参阅。选择的答案有效,但@nates解决方案也有效+1给你们两个。+1给答案,因为我想知道同样的问题,+1给答案,解释原因,+1给评论,给出最佳解决方案。编辑问题标题以反映问题。您还可以使用
@user.build\u shop(params)
这肯定是更好的方法。请注意,如果您多次创建\u shop,它将删除以前的店铺。例如,如果运行
@user.create\u shop(params[:shop\u one\u info])
它将创建shop\u one,但是如果运行
@user.create\u shop(params[:shop\u two\u info])
它将删除第一个店铺并创建第二个。上面关于删除以前店铺的注释是针对Rails 3.2.18的,不知道更新的版本。5分钟后无法编辑评论-找到解决方案,我没有在关联模型上设置唯一性,因此请确保按照此示例的商店模型中的设置方式进行设置。您也可以使用
@user.build\u商店(参数)
@user.create_shop(params[:shop])
Shop.create(user_id: user.id, title: 'Some unique title')