【问题标题】:Circular dependency detected while autoloading constant User自动加载常量用户时检测到循环依赖
【发布时间】:2013-08-03 11:56:28
【问题描述】:

我已按照本教程 (http://railscasts.com/episodes/236-omniauth-part-2) 使用 OmniAuth 和 Devise 创建 facebook 登录,但出现此错误:在我的 routes.rb 中自动加载常量用户时检测到循环依赖

  devise_for :users , :controllers => {:registrations => 'registrations'}

registrations_controller.rb

Class RegistrationsController < Devise::RegistrationsController

  def create
    super
    session[:omniauth] = nil unless @user.new_record?
  end

  private

  def build_resource(*args)
    super
    if session["devise.omniauth"]
      @user.apply_omniauth(session["devise.omniauth"])
      session["devise.omniauth"] = nil
   end
  end
end

这是我从 AuthenticationsController 中创建的方法

def create
    omniauth = request.env["omniauth.auth"]
    authentication = Authentication.find_by_provider_and_uid(omniauth['provider'], omniauth['uid'])
    if authentication
      flash[:notice] = "Signed in successfully."
      sign_in_and_redirect(:user, authentication.user)
    elsif current_user
      current_user.authentications.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
      flash[:notice] = "Authentication successful."
      redirect_to authentications_url
    else
      user = User.new
      user.apply_omniauth(omniauth)
      if user.save
        flash[:notice] = "Signed in successfully."
        sign_in_and_redirect(:user, user)
      else
        session[:omniauth] = omniauth.except('extra')
        redirect_to new_user_registration_url
      end
    end
end

【问题讨论】:

  • 你使用的是哪个版本的 rails / ruby​​?
  • rails 4.0.0.rc2 和 ruby​​ 1.9.3p448
  • 您能否提供完整的 stackstrace/errortrace 以便我们查明是哪个 gem 出现问题?
  • stacktraca 太长,无法放入评论
  • 我打赌 :registrations => 'registrations' 是循环依赖的原因。你能检查一下吗? :registration 是什么意思?

标签: ruby-on-rails ruby devise rubygems omniauth


【解决方案1】:

很多 gem 开始在 rails 4 中断,都是由于控制器中的 unloadable 问题。 https://github.com/flyerhzm/switch_user/issues/34 https://github.com/thoughtbot/high_voltage/issues/68 https://github.com/thoughtbot/clearance/issues/276 还有更多

您应该查看是哪个 gem 造成问题的错误。 一旦你知道: 1)检查该宝石的未解决问题 2)如果该问题存在并已修复,请确保您已修复该问题或更新 gem。 3)如果不是,您可以创建一个问题并要求他们修复它。 4)如果您不想等待他们的修复,您可以形成 gem 并为其推送修复 https://github.com/cashins/email_preview/commit/b34a077a954b98bd086153fae8979ad142667555 所有修复都是相同的(从指定的控制器中删除 unloadable )

希望对你有帮助。

如果没有任何帮助降级您的 Rails 版本。

【讨论】:

    【解决方案2】:

    我对 lib 中的某些类也有同样的问题(使用 config.autoload_paths += Dir["#{config.root}/lib/**/"]

    对我来说,帮助我将轨道从 4.0.0.rc1 切换到 4.0.0

    【讨论】:

      【解决方案3】:

      好吧,在我的 development.rb 中添加以下行后,我得到了解脱

      config.middleware.delete Rack::Lock
      

      参考: https://github.com/websocket-rails/websocket-rails/issues/101

      你终于可以试试这个了。

      【讨论】:

        【解决方案4】:

        我发现这在 development.rb 中有效:

        config.reload_classes_only_on_change = false
        

        (我之前尝试过删除 Gemfile.lock 并运行包更新,以及更改 Rails 版本,如此处和其他地方所述。它们对我不起作用。)

        【讨论】:

        • 我也试过删除锁并运行更新,没有任何效果。我应该在哪里添加该行?
        • 只需将其添加到 development.rb 的配置部分(我更新了答案)
        【解决方案5】:

        我也遇到过类似的问题。

        然后意识到我在控制器内的不同文件夹中复制了相同的文件,这就是问题所在。

        我的两个文件内容相同:

          app/controllers/logs_controller.rb
          app/controllers/api/logs_controller.rb
        

        【讨论】:

          【解决方案6】:

          设计 wiki 对这个话题有这样的说法:

          参考:https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in#preventing-redirect-loops

          防止重定向循环

          因为上面的 after_sign_in_path_for 代码只检查 request.referer == sign_in_url,这些方法(调用 after_sign_in_path_for)也必须被覆盖(否则你会遇到重定向循环):

          Devise::PasswordsController#after_resetting_password_path_for
          Devise::RegistrationsController#after_sign_up_path_for
          Devise::RegistrationsController#after_update_path_for
          

          可以这样做:

          # routes.rb
          devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords' }
          
          # users/registrations_controller.rb
          class Users::RegistrationsController < Devise::RegistrationsController
            protected
              def after_sign_up_path_for(resource)
                signed_in_root_path(resource)
              end
          
              def after_update_path_for(resource)
                signed_in_root_path(resource)
              end
          end
          
          # users/passwords_controller.rb
          class Users::PasswordsController < Devise::PasswordsController
            protected
              def after_resetting_password_path_for(resource)
                signed_in_root_path(resource)
              end
          end
          

          【讨论】:

          • OP 引用的具体错误是与自动加载有关的 Rails 错误,而不是与重定向循环有关的浏览器错误。
          • 我找到了 OPs 帖子并来到这里寻求答案,在自己寻找修复后,我回到这里并发布了对我有用的答案,即错误中提到的“循环依赖”消息与 Devise 的自动重定向方式有关。
          【解决方案7】:

          您的registrations_controller.rb 保存在哪里?位置很重要。我发现我把它保存到app/controllers/devise/. 时出错了。它只需要保存在app/controllers/. 例如:

          app/controllers/registrations_controller.rb


          另外,config/routes.rb 路由应该定义为:

          devise_for :users, controllers: { registrations: 'registrations' }

          【讨论】:

          • 这是为我做的。知道为什么吗?
          【解决方案8】:

          我用错字写了同样的错误,我有

          module EmployeeReminderssHelper
          

          何时调用帮助文件

          employee_reminders_helper.rb
          

          (注意多余的's')

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-10-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多