🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

391閲覧

user_idをaddress_usersテーブルに保存させたい

taka3344

総合スコア8

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/02/11 16:10

編集2021/02/11 16:12

user_idをaddress_userテーブルに保存させたい

保存までは上手くできたのですが、データの内容を見て見るとaddress_users内のuser_idがNULLになってしまっていました。
Rails6を使用してuser情報とaddress_user情報を一度に保存するウィザード機能を作成しています。
userモデルとaddress_userモデルはuserモデルを親とした、一対一のアソシエーションを組んでいました。

該当のソースコード

class Sellers::RegistrationsController < Devise::RegistrationsController def new @seller = Seller.new end # POST /resource def create @seller = Seller.new(sign_up_params) unless @seller.valid? render :new and return end session["devise.regist_data"] = {seller: @seller.attributes} session["devise.regist_data"][:seller]["password"] = params[:seller][:password] @address = @seller.build_address_seller render "address_sellers/new" end private def address_params params.require(:address_seller).permit(:postal_code, :area, :city, :block_number, :phone_number, :house_number) end class AddressSellersController < ApplicationController def new end def create @seller = Seller.new(session["devise.regist_data"]["seller"]) @address = AddressSeller.new(address_params) unless @address.valid? render :new and return end num = @seller.save @address.save(seller_id: num.id) session["devise.regist_data"]["seller"].clear sign_in(:seller, @seller) redirect_to :root end def address_params params.require(:address_seller).permit(:postal_code, :area, :city, :block_number, :phone_number, :house_number) end end

試したこと

num = @seller.save @address.save(seller_id: num.id)

と記述し、idを取得しようとしたのですが

NoMethodError in AddressSellersController#create
undefined method `id' for false:FalseClass

というエラーが出てしまいました。
binding.pryでデータが入っていないのか確認しましたが

pry(#<AddressSellersController>)> num = @seller.save
(0.4ms) BEGIN
↳ (pry):2:in create' Seller Exists? (0.9ms) SELECT 1 AS one FROM sellersWHEREsellers.email= BINARY 'momo@momo' LIMIT 1 ↳ (pry):2:increate'
(0.2ms) ROLLBACK
↳ (pry):2:in `create'
=> false
[3] pry(#<AddressSellersController>)> puts num
false
=> nil

nilとでてしまいました。

解決策を教えていただければ幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

@seller.save を処理しているところで、値は保存されているかと思います。
(ターミナルのログにも、INSERTかUPDATEのSQLが出力されていると思います)

ただし、saveメソッドの戻り値は、成功すればtrue、保存失敗ならfalse を返すので、num = @seller.save の結果numにはtrueかfalseの値が入ります。

Railsじゃないですが、rubyのインタプリタでfalseの値に対して .id を予防とすると同じエラーメッセージが出ます。

ruby

1irb(main):012:0> num.id 2Traceback (most recent call last): 3 4: from /usr/bin/irb:23:in `<main>' 4 3: from /usr/bin/irb:23:in `load' 5 2: from /Library/Ruby/Gems/2.6.x/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 6 1: from (irb):12 7NoMethodError (undefined method `id' for false:FalseClass)

さて、上記のエラーメッセージだと、undefined method `id' for false:FalseClass なので、falseが入っていて、保存に失敗していますね。

ROLLBACK ↳ (pry):2:in `create'

=> false
[3] pry(#<AddressSellersController>)> puts num
false
=> nil

このメッセージ通りに、失敗してROLLBACKしています。

(1) @seller.save で正しく保存されることを確認する

まずは、@seller.save で正しく保存されることを確認するのが良いと思います。
なにかバリデーションエラーとか、パラメータの引き渡しでのエラーが発生していると思いますので、ログに出ていると思います。

Seller Exists? (0.9ms) SELECT 1 AS one FROM sellers WHERE sellers.email = BINARY 'momo@momo' LIMIT 1

sellers.email = BINARY 'momo@momo'のsellerを取得してsaveする、という流れかな?そこでエラーになっていますね。

(2) @seller.saveが成功するとtrueが返ったあと

先ほどの通り、saveメソッドはtrue/faseを返すだけです。

また、save前はまだ保存されていなければIDが振られていないため、新規保存の場合は@sellerにはidが入っていません。
確実に割り当たったIDを取得したい場合は、
trueで成功したあとに @seller.reload で値を再読み込みできます。

ruby

1 2# saveメソッドで成功したら(trueなら) 3if @seller.save 4 num = @seller.reload 5 # ここでnumに@sellerの値が入っているか確認してみる 6 binding.pry 7 @address.save(seller_id: num.id) 8 session["devise.regist_data"]["seller"].clear 9 sign_in(:seller, @seller) 10 redirect_to :root 11 @address.save(seller_id: num.id) 12end

こんな感じで如何でしょうか。

投稿2021/02/11 23:09

suama

総合スコア1997

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taka3344

2021/02/13 06:26

ありがとうございます!! 無事保存ができました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問