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

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

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

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails

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

Authentication

Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。

Q&A

解決済

1回答

2839閲覧

railsでdevise、omniauthを使って複数SNSの認証に対応させるときにユーザーの作成ができない

y-temp4

総合スコア67

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails

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

Authentication

Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。

0グッド

0クリップ

投稿2016/06/09 13:43

###前提・実現したいこと
RailsでいろんなSNSとOAuth連携/ログインする方法を参考に複数SNSの認証をやろうとしているのですが、認証後にバリデーションの関係でエラーが出てしまいます。

原因は、SNSの認証後にメールアドレス、パスワードがなく、deviseのバリデーションに引っかかることなのですが、SNSによる認証を使わない時の登録はメールアドレスやパスワードが必要です。

SNSの認証を使うときのみメールアドレスとパスワードの認証をしないようにしたいのですが、方法がわかりません。

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

イメージ説明

###該当のソースコード

app/controllers/omniauth_callbacks_controller.rb

ruby

1class OmniauthCallbacksController < Devise::OmniauthCallbacksController 2 def facebook; basic_action; end 3 def github; basic_action; end 4 def google; basic_action; end 5 def hatena; basic_action; end 6 def linkedin; basic_action; end 7 def mixi; basic_action; end 8 def hatena; basic_action; end 9 10 private 11 def basic_action 12 @omniauth = request.env['omniauth.auth'] 13 if @omniauth.present? 14 @profile = SocialProfile.where(provider: @omniauth['provider'], uid: @omniauth['uid']).first 15 unless @profile 16 @profile = SocialProfile.where(provider: @omniauth['provider'], uid: @omniauth['uid']).new 17 @profile.user = current_user || User.create!(name: @omniauth['name']) # ここのユーザー作成時にエラーが出る(作成できない) 18 @profile.save! 19 end 20 if current_user 21 raise "user is not identical" if current_user != @profile.user 22 else 23 sign_in(:user, @profile.user) 24 end 25 @profile.set_values(@omniauth) 26 end 27 render :close, layout: false 28 end

###試したこと

Deviseのカスタマイズ。OAuthのときはemail入力を不必要にして、""でも可にするの記事にあるように、emailのインデックスを消し、nullを許可した場合、

app/models/user.rbで以下のように書くとSNS経由の登録はできるのですが、常にemailやpasswordが不要になるため困っています。

SNSを使った認証時にのみ、バリデーションを不要にしたいのですが...

ruby

1def email_required? 2 false 3end 4 5def password_required? 6 false 7end

また、Deviseのカスタマイズ。OAuthのときはemail入力を不必要にして、""でも可にするにあるように、下のように書くと別のエラーが出たためやめました。

ruby

1def email_required? 2 (authentications.empty? || !email.blank?) && super 3end

イメージ説明

###補足情報(言語/FW/ツール等のバージョンなど)

あまり関係ないかもしれませんが、バージョン情報をのせておきます。

  • Rails 5.0.0.rc1
  • Devise 4.1.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

任意のタイミングでバリデーションを実施するには、

ruby

1validates :field, presence: true, on: :hoge 2 3user.save(context: :hoge)

としてやればできるはずです。
が、この例だとSNS登録のときにcontextを指定するのではなく、一般登録でcontextを指定しなければならなくなるので、deviseのコントローラを少しいじらいないといけないですね。

formを切り出してやる方法もありますので、参考のリンクを貼っておきます。
Form Object実装メモ

投稿2016/06/10 04:29

ikea

総合スコア21

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

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

y-temp4

2016/06/10 06:58

回答ありがとうございます! 試行錯誤した結果、やはり一般登録でcontextを指定するためにdeviseコントローラをいじるのは気持ち悪いと思い、そうしない方法を模索しました。 試行錯誤した結果、以下のように`validate: false`を使えばいいんじゃないか?という結論に至りました(コードはまだ改善の余地がありそうですが)。 ``` # @profile.user = current_user || User.create!(name: @omniauth['info']['name']) @profile.user = current_user || User.new(name: @omniauth['info']['name']) @profile.user.save(validate: false) ``` 認証周りはまだまだやることがありそうなので、がんばります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問