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

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

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

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

3438閲覧

SNS認証プラグインにおけるuninitialized constantエラー

s.k

総合スコア423

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2016/11/04 05:12

編集2016/11/04 06:26

今、開発中のサイトで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に変更したり、別ファイルを作りそこにこのヘルパーを収納してみたりしました。ですが、できませんでした。

以上です。
よろしくお願いします((+_+))

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

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

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

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

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

hana-da

2016/11/04 06:17

o_auth_service/o_auth_policy.rb はどこに置いてありますかね? これも app/ からの path で書いてほしいです。
s.k

2016/11/04 06:27

hana-daさん お疲れ様です。★追加部分★に書きました!もし違っていればご指摘お願いします。
guest

回答1

0

ベストアンサー

お疲れの hana-da ですw

app/helpers/o_auth_service/o_auth_policy.rbapp/helpers/o_auth_policy.rb にすればいいような気がします。


サーバーの再起動はしましたよね?
それでダメなら分けてみますか。。。。(helpersに置いてあるのもちょっと気になりますが。。。。)

app/helpers/o_auth_policy/base.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 6end

app/helpers/o_auth_policy/facebook.rb

ruby

1module OAuthPolicy 2 class Facebook < OAuthPolicy::Base 3 def initialize(auth) 4 @provider = auth["provider"] 5 @uid = auth["uid"] 6 @name = auth["info"]["name"] 7 @nickname = "" 8 @email = "" 9 @url = "https://www.facebook.com/" 10 @image_url = auth["info"]["image"] 11 @description = "" 12 @credentials = auth["credentials"].to_json 13 @raw_info = auth["extra"]["raw_info"].to_json 14 freeze 15 end 16 end 17end

app/helpers/o_auth_policy/twitter.rb

ruby

1module OAuthPolicy 2 class Twitter < OAuthPolicy::Base 3 def initialize(auth) 4 @provider = auth["provider"] 5 @uid = auth["uid"] 6 @name = auth["info"]["name"] 7 @nickname = auth["info"]["nickname"] 8 @email = "" 9 @url = auth["info"]["urls"]["Twitter"] 10 @image_url = auth["info"]["image"] 11 @description = auth["info"]["description"].try(:truncate, 255) 12 @credentials = auth["credentials"].to_json 13 @raw_info = auth["extra"]["raw_info"].to_json 14 freeze 15 end 16 end 17end

こむずかしいですが 定数の自動読み込みと再読み込み に通常必要な事はだいたい書いてあります。

投稿2016/11/04 06:43

編集2016/11/04 06:52
hana-da

総合スコア1728

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

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

s.k

2016/11/04 06:48

試してみましたが、同様のエラー表示がでました( ;∀;) 【uninitialized constant OAuthPolicy::Twitter】 です…
s.k

2016/11/04 07:01 編集

hana-daさん、すいません。サーバーの再起動していませんでした。 再起動後に試したところ、違うエラーが出てきたので、 先程のエラーは解決できたと思います! エラー内容は 【NoMethodError in OmniauthCallbacksController#twitter】 【undefined method `skip_confirmation!' for #<User:0x0000000533c340>】 ちなみに、出たエラーはこんなんです! 今から取り組んでみたいと思います! このファイルはhelpersにはおかない方がいいんですか!
hana-da

2016/11/04 07:02

app/helpers は慣例的には view helper を置く場所ですね。
s.k

2016/11/04 07:07

そうですよね( ;∀;) 移動先見つけます。 どうしてapp/helpersに置かれているか調べてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問