1. ホーム
  2. ruby-on-rails

[解決済み] Rails: has_oneアソシエーションで作成する

2022-11-17 14:02:04

質問

こんにちは(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])

あちこちのガイドやチュートリアルを読んでいろいろなバリエーションを試しましたが、以前より混乱していて、うまくいきません。何か助けがあれば、非常にありがたいです。

どのように解決するのですか?

まず、やりたいことをやる方法を紹介します。

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

さて、あなたのバージョンがうまくいかなかった理由はここにあります。

おそらくあなたは、もしユーザが has_many の関係で、Shop に @user.shops.create(params[:shop]) となる のように動作します。しかし has_many の関係と has_one の関係で構成されています。

を持つ has_many の関係で shops はActiveRecordのコレクションオブジェクトを返します。このオブジェクトには、ユーザーへのショップの追加や削除に使用できるメソッドがあります。それらのメソッドのひとつは create で、これは新しいショップを作成し、ユーザーに追加します。

を使用すると has_one リレーションでは、そのようなコレクションオブジェクトは返されず、単にユーザーに属する Shop オブジェクト、あるいはユーザーがまだショップを持っていない場合は nil が返されます。Shop オブジェクトも nil も create メソッドを持っていないので create をこの方法で使うことはできません。 has_one の関係になります。