【问题标题】:Rails: create on has_one associationRails:在 has_one 关联上创建
【发布时间】:2011-04-19 21:08:01
【问题描述】:

嗨(这里是 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


【解决方案1】:

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

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

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

您可能认为这可能会起作用,因为如果 User 与 Shop 有 has_many 关系,@user.shops.create(params[:shop]) 起作用。但是has_many 关系和has_one 关系之间存在很大差异:

通过has_many 关系,shops 返回一个 ActiveRecord 集合对象,该集合对象具有可用于向用户添加和删除商店的方法。其中一种方法是create,它会创建一个新商店并将其添加给用户。

使用has_one 关系,您不会得到这样的集合对象,而只是属于用户的 Shop 对象 - 如果用户还没有商店,则返回 nil。由于 Shop 对象和 nil 都没有 create 方法,因此您不能以这种方式将 createhas_one 关系一起使用。

【讨论】:

  • 感谢您的回答,sepp2k。我现在明白为什么我的代码不能工作了。
  • 你也可以使用@user.create_shop(params[:shop])。见methods added by has_one
  • 选择的答案有效,但@nates 解决方案也有效。为你们俩 +1。
  • +1 回答,因为我也想知道,+1 回答解释为什么会这样,+1 评论给出最佳解决方案。
【解决方案2】:

更简洁的方法是:

@user.create_shop(params[:shop])

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

【讨论】:

  • 这绝对是更好的方法
  • 请注意,如果您多次创建_shop,它将删除以前的商店。例如,如果您运行 @user.create_shop(params[:shop_one_info]),它将创建 shop_one,但如果您运行 @user.create_shop(params[:shop_two_info]),它将删除第一个商店并创建第二个。
  • 以上关于删除以前的商店的评论是针对Rails 3.2.18的,不知道更新的版本。 5 分钟后无法编辑评论 -_-
  • 找到了解决方案,我没有在关联模型上设置唯一性,因此请确保按照本示例的 Shop 模型中的设置方式进行操作。
  • 你也可以使用@user.build_shop(params)
【解决方案3】:

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

shop = @user.build_shop
shop.save

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

【讨论】:

    【解决方案4】:

    只是添加到上面的答案 -

    @user.create_shop(params[:shop])
    

    上述语法会创建新记录,但随后会删除类似的现有记录。

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

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

    这个thread 可能会有所帮助。 Click here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多