今、開発中のサイトでSNS認証機能を実装したいです。
ユーザー登録時パスワードが不要になったりとユーザーにも運営側にもメリットがあるとわかりましたので取り組んでいます!
###前提・実現したいこと
twitter認証を実装したい。
facebook認証はなんとかできました。
下記の記事のコードをほぼそのまま利用させてもらってます。
Devise+OmniAuthでQiita風の複数プロバイダ認証
###発生している問題・エラーメッセージ
新規ユーザー登録画面上に、「twitterでログインする」リンクを作成しました。
リンクを押すと、下記画面に遷移し、数秒後にエラーが発生します。
【エラー内容】
NameError in OmniauthCallbacksController#twitter uninitialized constant OAuthPolicy::Twitter
調べたところ、モデル名がRailの記法に合っていない場合に発生するエラーであると書いてありました。ただ、どうあっていないのかがよくわかりません…
###該当のソースコード
流れはこのようになっています。
app/controllers/omniauth_callbacks_controller.rb:10:in `callback_for_all_providers' app/helpers/o_auth_service/get_o_auth_user.rb:7:in `call' app/models/social_profile.rb:9:in `find_for_oauth' app/models/social_profile.rb:17:in `save_oauth_data!' app/c:34:in `policy'←★エラー箇所★
【app/models/social_profile.rb:34:in `policy'】
ruby
132 def policy(provider, auth) 233 class_name = "#{provider}".classify 334 "OAuthPolicy::#{class_name}".constantize.new(auth) ←★OAuthPolicyをヘルパーで呼び出す際にエラーが起きている模様…★ 435 end
以下、関連ヘルパーのコードです。
2つとも同じファイルに入っています。
★追加部分★
【app/helpers/o_auth_service/o_auth_policy.rb】★本件のエラー原因だと思われるヘルパー★
★追加部分★
ruby
1module OAuthPolicy 2 class Base 3 attr_reader :provider, :uid, :name, :nickname, :email, :url, :image_url, 4 :description, :other, :credentials, :raw_info 5 end 6 7 class Facebook < OAuthPolicy::Base 8 def initialize(auth) 9 @provider = auth["provider"] 10 @uid = auth["uid"] 11 @name = auth["info"]["name"] 12 @nickname = "" 13 @email = "" 14 @url = "https://www.facebook.com/" 15 @image_url = auth["info"]["image"] 16 @description = "" 17 @credentials = auth["credentials"].to_json 18 @raw_info = auth["extra"]["raw_info"].to_json 19 freeze 20 end 21 end 22 23 class Twitter < OAuthPolicy::Base 24 def initialize(auth) 25 @provider = auth["provider"] 26 @uid = auth["uid"] 27 @name = auth["info"]["name"] 28 @nickname = auth["info"]["nickname"] 29 @email = "" 30 @url = auth["info"]["urls"]["Twitter"] 31 @image_url = auth["info"]["image"] 32 @description = auth["info"]["description"].try(:truncate, 255) 33 @credentials = auth["credentials"].to_json 34 @raw_info = auth["extra"]["raw_info"].to_json 35 freeze 36 end 37 end 38end
【app/helpers/o_auth_service/get_o_auth_user.rb】
ruby
1module OAuthService 2 class GetOAuthUser 3 4 def self.call(auth) 5 # 認証データに対応するSocialProfileが存在するか確認し、なければSocialProfileを新規作成。 6 # 認証データをSocialProfileオブジェクトにセットし、データベースに保存。 7 profile = SocialProfile.find_for_oauth(auth) 8 # ユーザーを探す。 9 # 第1候補:ログイン中のユーザー、第2候補:SocialProfileオブジェクトに紐付けされているユーザー。 10 user = current_or_profile_user(profile) 11 unless user 12 # 第3候補:認証データにemailが含まれていればそれを元にユーザーを探す。 13 user = User.where(email: email).first if verified_email_from_oauth(auth) 14 # 見つからなければ、ユーザーを新規作成。 15 user ||= find_or_create_new_user(auth) 16 end 17 associate_user_with_profile!(user, profile) 18 user 19 end 20 21 private 22 23 class << self 24 25 def current_or_profile_user(profile) 26 user = User.current_user.presence || profile.user 27 end 28 29 # 見つからなければ、ユーザーを新規作成。emailは後に確認するので今は仮のものを入れておく。 30 # TEMP_EMAIL_PREFIXを手掛かりに後に仮のものかどうかの判別が可能。 31 # OmniAuth認証時はパスワード入力は免除するので、ランダムのパスワードを入れておく。 32 def find_or_create_new_user(auth) 33 # Query for user if verified email is provided 34 email = verified_email_from_oauth(auth) 35 user = User.where(email: email).first if email 36 if user.nil? 37 temp_email = "#{User::TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com" 38 user = User.new( 39 username: auth.extra.raw_info.name, 40 email: email ? email : temp_email, 41 password: Devise.friendly_token[0,20] 42 ) 43 # email確認メール送信を延期するために一時的にemail確認済みの状態にする。 44 user.skip_confirmation! 45 # email仮をデータベースに保存するため、validationを一時的に無効化。 46 user.save(validate: false) 47 user 48 end 49 end 50 51 def verified_email_from_oauth(auth) 52 auth.info.email if auth.info.email && (auth.info.verified || auth.info.verified_email) 53 end 54 55 # ユーザーとSocialProfileオブジェクトを関連づける。 56 def associate_user_with_profile!(user, profile) 57 profile.update!(user_id: user.id) if profile.user != user 58 end 59 end 60 end 61end
###試したこと
①実は、このエラーの前にも同種のエラーが起きました。
その際は、ネットに記事が落ちていましたので、それを参考にし解決できました。
Ruby on Rails、Controllerからhelpersフォルダのクラスを使おうとするとuninitialized constantが発生する。
②、①ではヘルパーのフォルダ名を変更し、ヘルパー自身の名前も変更すると解決できたので、今回も同様にo_auth_policyをget_auth_policyに変更したり、別ファイルを作りそこにこのヘルパーを収納してみたりしました。ですが、できませんでした。
以上です。
よろしくお願いします((+_+))
回答1件
あなたの回答
tips
プレビュー