【问题标题】:OmniAuth / Rails - You have a nil object when you didn't expect itOmniAuth / Rails - 当你没有预料到它时,你有一个 nil 对象
【发布时间】:2011-01-16 13:04:43
【问题描述】:

我的 Rails 应用程序出现以下错误,我不知道如何调试或修复它:

NoMethodError 在 AuthenticationsController#create

当你没有时你有一个 nil 对象 期待它!你可能已经预料到了 ActiveRecord::Base 的实例。这 评估 nil 时出错。[]

Rails.root: /Users/phil/Sites/travlrapp.com 应用程序跟踪 |框架跟踪 | 全程跟踪

app/controllers/authentications_controller.rb:15:in `创建'

控制器是这样的:

class AuthenticationsController < ApplicationController
  def index
    @authentications = current_user.authentications if current_user
  end

    def create

        omniauth = request.env["omniauth.auth"]

        unless omniauth
            redirect_to authentications_url
            flash[:notice] = "Could not authenticate via #{params['provider']}."
        end

        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'], :token => omniauth['credentials']['token'], :secret => omniauth['credentials']['secret'])
            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


  def destroy
    @authentication = current_user.authentications.find(params[:id])
    @authentication.destroy
    flash[:notice] = "Successfully destroyed authentication."
    redirect_to authentications_url
  end
end

OmniAuth 以前可以正常工作,然后我将其混搭起来,试图通过支持 flickr 的 pchilton 交换到一个 fork。我通过在 gemfile 中设置 :git => 并尝试重新安装来做到这一点,但我不相信我做对了。

我现在手动删除了所有omniauth 和o-foo gem 文件,并首先安装了当前的stable (0.1.6) 和git 主副本,但所有错误都是一样的。

这里真的很茫然,我认识的人都不知道问题出在哪里。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 omniauth


    【解决方案1】:

    omniauth 很可能是nil。当您使用 unless onmniauth 检查 nil 时,redirect_to 实际上并没有阻止下面的控制器代码执行。

    你可能想要这样的东西:

    unless omniauth
      redirect_to authentications_url
      flash[:notice] = "Could not authenticate via #{params['provider']}."
      return
    end

    现在,您仍然需要弄清楚为什么 omniauthnil。为此,请查看 README,确保您正确使用 OmniAuth。 /auth/provider/callback 是否路由到 AuthenticationsController#create

    【讨论】:

      【解决方案2】:

      如果您已经知道这种方法,我提前道歉(毕竟您是一个 php 开发人员)。

      rails 是否支持类似于die() 的php 样式调试?我在 yii 和 kohana php 框架中都遇到过这样奇怪的难以理解的错误。

      我所做的是在控制器动作的末尾放置一个die('AAAAA'),然后逐渐向上移动,直到 IT 在错误发生之前触发,这样我就可以准确地知道在哪一行错误是。

      然后我将它移动到该行调用的任何函数中并重新开始。

      我不知道rails 是否支持这种原始调试风格。如果这些 gem 的源代码在非编译代码中也会有所帮助,这样您就可以像这样在整个地方插入 die()

      你可以做类似echo 'AAA'; exit;或类似的事情。

      还有'检查函数是否被调用:die('BBBBB');:P

      如果你想真正进阶,还有

      die("AAAAA ".' '.__FILE__.'::Line:'.__LINE__);

      【讨论】:

      • 当然,这种调试在 PHP 中可以正常工作,但在 Rails 中有点不同。您可以使用 puts "foo" 输出到控制台而不是浏览器,这就像一个“断点”,表明 rails 已读取该行。对我来说,Puts 似乎被忽略了,这是我在调试时遇到的一个问题,但现在似乎可以工作了。这很奇怪。
      • 如果您使用的是 Ruby 1.9,您还可以使用 Object#tap 注入调试代码,而无需添加单独的 puts 语句。见这里:blog.moertel.com/articles/2007/02/07/…
      • 你也可以raise对象(raise omniauth)。它会导致错误并很好地打印出对象。
      【解决方案3】:

      这似乎是随机修复的。使用 Rails!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-26
        • 2015-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多