【问题标题】:Rails undefined method `find_or_create_from_auth_hash'Rails 未定义方法`find_or_create_from_auth_hash'
【发布时间】:2013-07-01 07:32:01
【问题描述】:

我的 session_controller 如下:

class SessionsController < ApplicationController
require 'omniauth-facebook'
require 'omniauth'
def create
@user = User.find_or_create_from_auth_hash(auth_hash)
self.current_user = @user
redirect_to '/'
end

protected

def auth_hash
request.env['omniauth.auth']
end
end

所以...不是吗?

这是我的 users.rb 文件:

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

# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
has_many :posts
has_many :tasks
end

还有我的路线文件:

LiquidAdmin::Application.routes.draw do
devise_for :users

get '/auth/:provider/callback', to: 'sessions#create'

resource :sessions, :only => :create

get "home/bandwall"
get "home/index"
root :to => "home#index"

那么问题出在哪里? “auth_hash”已明确定义...... SessionsController 正在加载......那为什么它抱怨没有 find_or_create_from_auth_hash 的方法?

【问题讨论】:

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


    【解决方案1】:

    在 Rails 3.2 中,您要使用的方法称为 first_or_create

    User.where(auth_hash: auth_hash).first_or_create
    

    根据Rails 3.2 release notes

    添加 first_or_create、first_or_create!、first_or_initialize 方法到 活动记录。这是比旧方法更好的方法 find_or_create_by 动态方法,因为它更清楚哪些参数 用于查找记录并用于创建记录。

    鉴于此,通过查询可以实现以下操作:

    User.where(auth_hash: auth_hash).first_or_create(foo: 'bar') # Assuming no other User entries exist
    #=> #<User id: 1, auth_hash: "your_auth_hash", foo: "bar">
    
    User.where(auth_hash: auth_hash).first_or_create(foo: 'baz')
    #=> #<User id: 1, auth_hash: "your_auth_hash", foo: "bar">
    

    【讨论】:

    • 好的。我将行更改为 @user = User.where(auth_hash: auth_hash).first_or_create 但现在我收到此错误:“SQLite3::SQLException: no such column: auth_hash.provider: SELECT "users".* FROM "users " WHERE "auth_hash"."provider" = 'facebook' AND "auth_hash"."uid" = '672086173' AND "auth_hash"."info" = '--- !ruby/hash:OmniAuth::AuthHash::InfoHash "
    • 您需要在 AuthHash 模型上为 provider 创建迁移。从命令行尝试rails g migration AddProviderToAuthHash provider:string,然后运行rake db:migrate
    • 如果这个答案有效(正如您和其他人所指出的那样),您会考虑接受它是正确的吗?我很高兴解决您持续存在的问题(请参阅我之前的评论),但它的范围显然比您原来的问题更加短视。由于此答案正确解决了您的原始问题,因此如果您接受它是正确的,它将对其他用户有所帮助。
    • 对不起。以为我做到了。 :) 完成!
    • 认真的吗?你已经有 12,000 多的声望了……该死的那个男人/女孩。
    【解决方案2】:

    鉴于这个问题是基于 OmniAuth,我认为更好的答案是:

    @user = User.where(auth_hash).first_or_create
    

    或者如果 Rails 版本大于 4.1.14

    @user = User.where(uid: auth_hash[:uid], provider: auth_hash[:provider]).first_or_create
    

    auth_hash 不是User 模型中的字段,而是Hash 可能在User 模型中的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      • 2013-02-05
      • 2012-04-09
      相关资源
      最近更新 更多