naichi's lab

3日後の自分(他人)への書き置き

Ruby on Rails、Controllerからhelpersフォルダのクラスを使おうとするとuninitialized constantが発生する。

Devise+OmniAuthでQiita風の複数プロバイダ認証 - Qiita

ここを参考にomniauthログインを実装してる。

deviseは使ってないので若干違うけど。

やりたいこと

Railsチュートリアルを真似て作ったSessions#createをomniauthのコールバックで書き換える。

実装内容

とりあえず書かれてる通りにapp/helpers/o_auth/o_auth_policyapp/helpers/o_auth/o_auth_serviceを作った。

module OAuthService
  class GetOAuthUser
    def self.call(auth)
      # 実装〜
    end

    # 色々実装〜
  end
end

そしてsessions_controllercallback_for_all_providers関数を用意した。(参考記事のまま)

TwitterDevで上記メソッドがコールバック先となるようにroutingを設定でアクセス。

f:id:naichilab:20160303230546p:plain

ここまではOK。

しかしエラー、、、

f:id:naichilab:20160303230705p:plain

エラー内容

NameError in SessionsController#callback_for_all_providers
uninitialized constant SessionsController::OAuthService

エラー箇所のソース

  def callback_for_all_providers
    unless env["omniauth.auth"].present?
      flash[:danger] = "Authentication data was not provided"
      redirect_to root_url and return
    end
    provider = __callee__.to_s
    user = OAuthService::GetOAuthUser.call(env["omniauth.auth"])
    # ユーザーがデータベースに保存されており、且つemailを確認済みであれば、ユーザーをログインする。
    if user.persisted? && user.email_verified?
      sign_in_and_redirect user, event: :authentication
      set_flash_message(:notice, :success, kind: provider.capitalize) if is_navigational_format?
    else
      user.reset_confirmation!
      flash[:warning] = "We need your email address before proceeding."
      redirect_to finish_signup_path(user)
    end
  end

user = OAuthService::GetOAuthUser.call(env["omniauth.auth"])の行でuninitialized constant SessionsController::OAuthServiceっていうエラーしてる。

callback_for_all_providersメソッドはSessionsControllerに実装してあるからSessionsController名前空間の下を探しに行ってるんだよなぁ。

OAuthServiceはこんな感じで定義してあるから最上位の名前空間?から検索すればいけそうな気がするけどどうやるんやろ。

f:id:naichilab:20160303231309p:plain

2016/03/04 解決

参考

ruby on rails - railsでgrapeを使用した場合” Unable to autoload constant API,〜(LoadError)”というエラー - スタック・オーバーフロー

自動読み込みされるかどうかはクラス名やフォルダ名によって変わるらしい。

とりあえずこんな感じの構成に変えてみた。

f:id:naichilab:20160304090427p:plain

そしてSessionsController内での呼び出しをuser = OAuthService::GetOAuthUser.call(env["omniauth.auth"])って書き方にしたら動いた。

最初に参考にしたQiita記事はオートロードパスを設定してたんだろうか?