неинициализированные постоянные пользователи для omniauth_callbacks_controller с gem omniauth-facebook в приложении ruby ​​on rails

У меня проблемы с devise и omniauth-facebook с рельсами. Я установил gem omniauth-facebook и gem devise.

Я установил секрет и ключи fb в config/application.yml. Я настроил устройство в # config/initializers/devise.rb:

Devise.setup do |config|
  config.omniauth :facebook, ENV["FB_ID"], ENV["FB_SECRET"], scope: 'email', info_fields: 'email, first_name,last_name', image_size: 'large'
end

Я изменил свои маршруты следующим образом:

config/routes.rb

Rails.application.routes.draw do
  devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
end

Я изменил свою пользовательскую модель:

# app/models/user.rb

class User < ActiveRecord::Base
  devise :omniauthable, omniauth_providers: [:facebook]
end

Я добавил следующую миграцию рельсов:

$ rails g migration AddOmniauthToUsers \
    provider uid picture first_name last_name token token_expiry:datetime
$ rake db:migrate

В моей модели пользователя:

# app/models/user.rb
class User < ActiveRecord::Base
  def self.find_for_facebook_oauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]  # Fake password for validation
      user.first_name = auth.info.first_name
      user.last_name = auth.info.last_name
      user.picture = auth.info.image
      user.token = auth.credentials.token
      user.token_expiry = Time.at(auth.credentials.expires_at)
    end
  end
end

Я создал новый контроллер для обработки запроса обратного вызова Omniauth.

# app/controllers/users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    user = User.find_for_facebook_oauth(request.env['omniauth.auth'])

    if user.persisted?
      sign_in_and_redirect user, event: :authentication
      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
    end
  end
end

Мое соединение с facebook работает в моем локальном приложении, но оно с самого начала приводит к сбою приложения на героку с этим сообщением об ошибке:

Я правильно установил свои переменные среды на героку и героку запустить rake db:migrate.

Откуда берется эта ошибка и как ее исправить?

/app/app/controllers/Users/omniauth_callbacks_controller.rb:1:in `<top (required)>': uninitialized constant Users (NameError)
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:472:in `block (2 levels) in eager_load!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:471:in `each'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:471:in `block in eager_load!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:469:in `each'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:469:in `eager_load!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/engine.rb:346:in `eager_load!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application/finisher.rb:56:in `each'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application/finisher.rb:56:in `block in <module:Finisher>'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `instance_exec'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:30:in `run'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:55:in `block in run_initializers'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `call'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
    from /app/vendor/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/initializable.rb:54:in `run_initializers'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application.rb:352:in `initialize!'
    from /app/config/environment.rb:5:in `<top (required)>'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/application.rb:328:in `require_environment!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:142:in `require_application_and_environment!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:67:in `console'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /app/vendor/bundle/ruby/2.3.0/gems/railties-4.2.6/lib/rails/commands.rb:17:in `<top (required)>'
    from /app/bin/rails:9:in `require'
    from /app/bin/rails:9:in `<main>'

person David Geismar    schedule 22.07.2016    source источник


Ответы (1)


1-е возможное решение:

Ошибка имени неинициализированного константного класса произойдет, если ваша консоль rails не загружена конфигурацией файла класса, содержащего вызываемый метод. Это означает, что класс просто не был загружен приложением.

Видите ли вы этот config.autoload_paths += %W(#{config.root}/lib) в вашем файле application.rb? если нет, можете ли вы положить его туда и попробовать еще раз? дайте мне знать, как это происходит.

2-е возможное решение:

попробуйте вернуться к:

 devise_for :users, controllers: { omniauth_callbacks: 'omniauth_callbacks' 

и, конечно же, переместить chnaged

class OmniauthCallbacksController < Devise::OmniauthCallbacksController

в приложение/контроллеры/omniauth_callbacks_controller.rb

надеюсь это поможет! дай мне знать

person Community    schedule 22.07.2016
comment
у вас есть объяснение, почему это не сработало? - person David Geismar; 23.07.2016
comment
Я все еще думаю, что это связано с тем, как приложение загружает константы. Это должно быть хорошо без первого, что я предложил, но в принципе вы должны загружать константы по мере загрузки приложения. Иногда версии рельсов делают что-то по-разному, поэтому не уверен, как ваше приложение настроено глобально и какие версии у вас есть для вещей. Или иногда это просто ide, который вы используете ... Я сам прошел через то же самое с devise omniauth fb, и у меня есть мой контроллер в controllers/users/omniauth_callbacks_controller.rb, и он работает нормально. Извините, я знаю, что это явно не отвечает на ваш вопрос. - person ; 23.07.2016