質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 6

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

Q&A

解決済

2回答

907閲覧

SNS認証における問題 Mysql2::Error: Field 'user_id' doesn't have a default value

Malson

総合スコア10

Ruby on Rails 6

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

0グッド

0クリップ

投稿2020/07/30 12:12

前提・実現したいこと

SNS認証機能をサインアップ画面に実装しているのですが、データをうまく保存させることができません。
SNS認証で初回登録された際に、
Userテーブルの子であるSnsCredentialテーブルに、外部キーのuser_idを除いたデータを格納し、
また、Userテーブルにも返り値のデータが格納されるようにしたい。
その後、再度ログインした時にはSnsCredentialテーブルにuser_idも番号が割り振られる様に設定という流れを実現したいと考えています。

発生している問題・エラーメッセージ

現在、表題の通りで、user_idにdefault値が無いため、エラーになっていますとあります。
モデルにdefault: NULLとしても効果がなく、
使用しているSQLに直接NULL許可を付与すると、SNSCredentialテーブルだけにはデータが保存される様になります
(*これは本番環境には使えない手なので、あくまで実験的に行ったものですが)
イメージ説明

どの様な対応が必要なのでしょうか?

該当のソースコード

migration

1 def change 2 create_table :sns_credentials do |t| 3 t.string :provider 4 t.string :uid 5 t.references :user, foreign_key: true 6 end

controller

1 def google_oauth2 2 authorization 3 end 4 ~~~~略~~~~~ 5 private 6 def authorization 7 @user = User.from_omniauth(request.env["omniauth.auth"]) 8 if @user.persisted? 9 ~~~~略~~~~~ 10 end 11 end

SnsCredentialModel

1belongs_to :user, optional: true

UserModel

1 has_many :sns_credentials 2 def self.from_omniauth(auth) 3 sns = SnsCredential.where(provider: auth.provider, uid: auth.uid).first_or_create 4 user = sns.user || User.where(email: auth.info.email).first_or_initialize( 5 nickname: auth.info.name, 6 email: auth.info.email 7 ) 8 if user.persisted? 9 ~~~~~略~~~~~~~ 10 end 11end

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

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

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

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

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

guest

回答2

0

t.references :user, foreign_key: true

この foreign_key: true が効いてるような気がする。

初めから user_idを入れることはできません?

投稿2020/07/30 23:08

winterboum

総合スコア23329

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

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

Malson

2020/07/31 00:19

winterboum様、 ありがとうございます。 モデルの設計として、Userの外部キーとしてデータを保存したいので、user_idにするのはできないのです。 最初はNULL許可でいけるかなと考えていたのですが、根本違うのかもしれません。
Malson

2020/07/31 00:39

多分解決できたと思うのですが、 コントローラーの@userの不備だと思います。 まだ動作が正常で無いので、他に問題があるのかと測りかねる感じです。
guest

0

自己解決

sns = SnsCredential.where(provider: auth.provider, uid: auth.uid).first_or_create
の.first_or_createを.first_or_initializeに変更することで解決した。

whereメソッド以下の内容の検索結果から最初の1つめを受け取るか、なかった場合は検索条件でcreateが実行される。当然、サインアップ時はcreateが実行されることになるが、
この中にuser_idの条件設定がないし、加えられないので、createではなくnewを実行するfirst_or_initializeメソッドを実行することで対応できた。

当初想定していた動きと異なるがひとまずの解決になりました。

投稿2020/07/31 11:18

Malson

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問