2015년 12월 15일 화요일

Routing Error uninitialized constant Users

Routing Error uninitialized constant 는 연관 클래스 파일의 위치가 잘못된 경우 발생하게 된다.


I am a rails newbie... I am trying to set up Sign in with facebook for a demo app. I am using OmniAuth and following this tutorial
I get this error when redirecting to fB:
   Routing Error:

    uninitialized constant Users

    Try running rake routes for more information on available routes. 
Environment
Windows 7
Rails version :3.2.9.rc2
omniauth-1.1.1
devise-2.1.2
My routes.rb looks like this:
  root :to => 'static_pages#home'
  resources :users
  get "static_pages/home"
  match '/auth/facebook' => 'omniauth#passthru'
  match '/users/auth/facebook' => 'users/omniauth_callbacks#passthru'
  devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" } , :strategy_class => OmniAuth::Strategies::Facebook
devise.rb contains:
require 'devise/orm/active_record'
require 'omniauth-facebook'

config.omniauth_path_prefix = "/users/auth"
  config.omniauth :facebook, "ABC", "XYZ",{:client_options => { :ssl => { :verify => false } }} 
And OmniAuthController contains: i.e. app/controllers/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def facebook
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      #redirect_to new_user_registration_url
      redirect_to "static_pages_home"
    end
  end 

  def passthru
    render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
    # Or alternatively,
    # raise ActionController::RoutingError.new('Not Found')
  end


end
The model User.rb contains:
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable 

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
  attr_accessible :date_of_birth, :firstName, :lastName, :mailId, :phone, :provider, :uid
  devise :omniauthable

 protected


 def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.find(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(name:auth.extra.raw_info.name,
                           provider:auth.provider,
                           uid:auth.uid,
                           email:auth.info.email,
                           password:Devise.friendly_token[0,20]
                           )
    end
    user
  end  

 def self.new_with_session(params, session)
    super.tap do |user|
      if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
        user.email = data["email"] if user.email.blank?
      end
    end
  end

end
Trace:
Started GET "/users/auth/facebook" for 127.0.0.1 at 2012-11-23 22:39:32 -0800 (facebook) Callback phase initiated.
Started GET "/users/auth/facebook/callback?
state=XYZ&code=ABC" for 127.0.0.1 at 2012-11-23 22:39:33 -0800

ActionController::RoutingError (uninitialized constant Users):
  activesupport (3.2.9.rc2) lib/active_support/inflector/methods.rb:230:in `block in constantize'
  activesupport (3.2.9.rc2) lib/active_support/inflector/methods.rb:229:in `each'
  activesupport (3.2.9.rc2) lib/active_support/inflector/methods.rb:229:in `constantize'
  actionpack (3.2.9.rc2) lib/action_dispatch/routing/route_set.rb:69:in `controller_reference'
  actionpack (3.2.9.rc2) lib/action_dispatch/routing/route_set.rb:54:in `controller'
  actionpack (3.2.9.rc2) lib/action_dispatch/routing/route_set.rb:32:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/routing/mapper.rb:42:in `call'
  journey (1.0.4) lib/journey/router.rb:68:in `block in call'
  journey (1.0.4) lib/journey/router.rb:56:in `each'
  journey (1.0.4) lib/journey/router.rb:56:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/routing/route_set.rb:600:in `call'
  omniauth (1.1.1) lib/omniauth/strategy.rb:394:in `call_app!'
  omniauth (1.1.1) lib/omniauth/strategy.rb:356:in `callback_phase'
  omniauth-oauth2 (1.1.1) lib/omniauth/strategies/oauth2.rb:77:in `callback_phase'
  omniauth (1.1.1) lib/omniauth/strategy.rb:219:in `callback_call'
  omniauth (1.1.1) lib/omniauth/strategy.rb:175:in `call!'
  omniauth (1.1.1) lib/omniauth/strategy.rb:157:in `call'
  warden (1.2.1) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.1) lib/warden/manager.rb:34:in `catch'
  warden (1.2.1) lib/warden/manager.rb:34:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
  rack (1.4.1) lib/rack/etag.rb:23:in `call'
  rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/head.rb:14:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/flash.rb:242:in `call'
  rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
  rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/cookies.rb:341:in `call'
  activerecord (3.2.9.rc2) lib/active_record/query_cache.rb:64:in `call'
  activerecord (3.2.9.rc2) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
  activesupport (3.2.9.rc2) lib/active_support/callbacks.rb:405:in `_run__959081092__call__942932381__callbacks'
  activesupport (3.2.9.rc2) lib/active_support/callbacks.rb:405:in `__run_callback'
  activesupport (3.2.9.rc2) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
  activesupport (3.2.9.rc2) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/reloader.rb:65:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.9.rc2) lib/rails/rack/logger.rb:32:in `call_app'
  railties (3.2.9.rc2) lib/rails/rack/logger.rb:16:in `block in call'
  activesupport (3.2.9.rc2) lib/active_support/tagged_logging.rb:22:in `tagged'
  railties (3.2.9.rc2) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.1) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.9.rc2) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.1) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.9.rc2) lib/action_dispatch/middleware/static.rb:62:in `call'
  railties (3.2.9.rc2) lib/rails/engine.rb:479:in `call'
  railties (3.2.9.rc2) lib/rails/application.rb:223:in `call'
  rack (1.4.1) lib/rack/content_length.rb:14:in `call'
  railties (3.2.9.rc2) lib/rails/rack/log_tailer.rb:17:in `call'
  rack (1.4.1) lib/rack/handler/webrick.rb:59:in `service'
  c:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
  c:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
  c:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'


  Rendered c:/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.9.rc2/lib/action_dispatch/middleware/templates/rescues/
ing_error.erb within rescues/layout (0.0ms)
shareimprove this question
   
Can you provide the trace? – uDaY Nov 24 '12 at 0:57
1 
This is an exact duplicate of this question. Try searching for your error next time :) If you want your controller named Users::OmniauthCallbacksController then it needs to be inapp/controllers/users/omniauth_callbacks_controller.rb. If you don't want nested folders for your controllers then simply name your controller class OmniauthCallbacksController < Devise::OmniauthCallbacksController – Ashitaka Nov 24 '12 at 2:06 
   
@uDaY: I have added the trace... – amit modi Nov 24 '12 at 6:45
   
@Ashitaka: Thanks for the quick response.. I have already tried changing the name and that did not work:) – amit modi Nov 24 '12 at 6:46
   
I bet you changed the name and left the route still pointing to users/omniauth_callbacks. Either you remove the users part or you have to put your controller inside a users folder. – Ashitaka Nov 24 '12 at 15:13

2 Answers

up vote51down voteaccepted
mv
app/controllers/omniauth_callbacks_controller.rb
to
app/controllers/users/omniauth_callbacks_controller.rb
or change
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
to
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
shareimprove this answer
2 
This is sooo much better answer , and it points directly to the problem. And also clean! thanks – Aleks Mar 15 '13 at 19:32
I believe that part is messing up:
match '/users/auth/facebook' => 'users/omniauth_callbacks#passthru'
Little test, for you:
put in your view:
<%= link_to users_auth_facebook_path, users_auth_facebook_path  %>
and follow it with click, it also gives very same error...
I believe you should use something like (what is mentioned in wiki you linked above):
devise_scope :user do
  get '/users/auth/:provider' => 'users/omniauth_callbacks#passthru'
end
And wrap passthru method to delegate action to appropriate private/protected method depending on params[:provider] value
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def passthru
    send(params[:provider]) if providers.include?(params[:provider])
  end

  protected

  def facebook
    raise "Implement me for facebook"
  end

  def twitter
    raise "Implement me for twitter"
  end

  private

  def providers
    ["facebook", "twitter"]
  end
end
shareimprove this answer

댓글 없음: