【问题标题】:undefined local variable or method `user' omniauth callbacks controller未定义的局部变量或方法“用户”omniauth 回调控制器
【发布时间】:2014-11-22 05:30:59
【问题描述】:

我正在尝试使用 devise 和 omniauth 实现 facebook 登录身份验证,但在回调部分出现错误。

错误是这样的......

> `User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."provider" = ? AND "users"."uid" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["provider", "facebook"], ["uid", "1517802078458724"]]
   (0.1ms)  begin transaction
   (0.1ms)  rollback transaction
Completed 500 Internal Server Error in 411ms

NameError (undefined local variable or method `user' for #<User:0x007f3008b8a760>):
  app/models/user.rb:34:in `password_required?'
  app/models/user.rb:18:in `block in from_omniauth'
  app/models/user.rb:12:in `tap'
  app/models/user.rb:12:in `from_omniauth'
  app/controllers/omniauth_callbacks_controller.rb:4:in `all'`

似乎在 /auth/facebook/ 之前一切正常,然后一直到检索 uid 和提供程序结束的部分。

我在控制器、模型和路由中的代码如下..

用于回调控制器和应用程序控制器

  class OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def all
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      sign_in_and_redirect user, notice: "Signed in!"
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :facebook, :all
end


class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

end

我的 user.rb 模型

class User < ActiveRecord::Base
  has_many :authentications
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :omniauthable,
         :recoverable, :rememberable, :trackable, :validatable,
         :omniauth_providers => [:facebook]

  attr_accessible :email, :password, :password_confirmation

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_initialize.tap do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.name = auth.info.name
      user.oauth_token = auth.credentials.token
      user.oauth_expires_at = Time.at(auth.credentials.expires_at)
      user.save!
    end
  end

  def self.new_with_sessions(params, session)
    if session["devise.user_attributes"]
      new(session["devise.user_attributes"], without_protection: true ) do |user|
        user.attributes = params
        user.valid?
      end
    else
      super
    end
  end

  def password_required?
    super && user.blank?

  end
end

我的 schema.rb

ActiveRecord::Schema.define(版本:20141120211712)做

create_table "users", force: true do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "provider"
    t.string   "uid"
    t.string   "name"
    t.string   "oauth_token"
    t.datetime "oauth_expires_at"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

我的路线.rb

Rails.application.routes.draw do

  devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" } 
  root            'static_pages#home'
  get 'help' =>   'static_pages#help'
  get 'about' =>  'static_pages#about'
  get 'contact' => 'static_pages#contact'

最后是我的 gemfile

source 'https://rubygems.org'
ruby   '2.1.4'

gem 'rails',                   '4.2.0.beta4'
gem 'bcrypt',                  '3.1.7'
gem 'faker',                   '1.4.2'
gem 'carrierwave',             '0.10.0'
gem 'mini_magick',             '3.8.0'
gem 'fog',                     '1.23.0'
gem 'will_paginate',           '3.0.7'
gem 'bootstrap-will_paginate', '0.0.10'
gem 'bootstrap-sass',          '3.2.0.0'
gem 'sass-rails',              '5.0.0.beta1'
gem 'uglifier',                '2.5.3'
gem 'coffee-rails',            '4.0.1'
gem 'jquery-rails',            '4.0.0.beta2'
gem 'turbolinks',              '2.3.0'
gem 'jbuilder',                '2.2.3'
gem 'rails-html-sanitizer',    '1.0.1'
gem 'sdoc',                    '0.4.0', group: :doc
gem 'devise', github: 'plataformatec/devise'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-facebook'
gem 'omniauth-linkedin'
gem 'figaro'
gem 'protected_attributes'

我真的很想在我的应用程序中使用这个 facebook 登录功能...提前非常感谢您。我将不胜感激任何意见..

【问题讨论】:

    标签: ruby-on-rails-4 devise omniauth-facebook


    【解决方案1】:

    问题在于保存用户时调用的password_required?

    def password_required?
      super && user.blank?
    
    end
    

    它试图测试user 是否为空白?但是,用户变量/方法在其范围内不存在。相反,您需要使用 self 来引用当前的 User 实例。

    所以该行应该是:

    super && self.blank?
    

    或者只是:

    super && blank?
    

    【讨论】:

    • 现在我得到 ActiveRecord::RecordInvalid(验证失败:电子邮件不能为空):错误。我现在该怎么办?
    【解决方案2】:

    我能够通过制作解决这个问题

    def password_required?
      super && user.blank?
    
    end
    

    进入

    super && self.blank?
    

    我还加了

    user.email = auth.info.email
    

    self.from_omniauth(auth) 部分。 谢谢大家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多