【问题标题】:NoMethodError (undefined method `persisted?' for nil:NilClass):NoMethodError(未定义的方法 `persisted?' for nil:NilClass):
【发布时间】:2012-08-31 16:47:43
【问题描述】:

NoMethodError(未定义的方法 `persisted?' for nil:NilClass):

这是我在尝试将 omniauth 与 Devise 一起使用时遇到的错误...

我可以使用 facebook 注册该网站... 但是一旦我注销 并尝试重新登录我得到了

NoMethodError(未定义的方法 `persisted?' for nil:NilClass):

类模型::OmniauthCallbacksController

定义脸书 # 你需要在你的模型中实现下面的方法(例如app/models/user.rb) @model = Model.find_for_facebook_oauth(request.env["omniauth.auth"], current_model)

if @model.persisted?
  flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
  sign_in_and_redirect @model, :event => :authentication
else
  session["devise.facebook_data"] = request.env["omniauth.auth"]
  redirect_to new_model_registration_url
end

结束

def passthru 渲染 :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false # 或者, # raise ActionController::RoutingError.new('Not Found') 结束

结束

模型.rb

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

  # Setup accessible (or protected) attributes for your model
  attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :provider, :uid
  # attr_accessible :title, :body

  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    model = Model.where(:provider => auth.provider, :uid => auth.uid).first
    unless model
    model = Model.create(name:auth.extra.raw_info.name,
                         provider:auth.provider,
                         uid:auth.uid,
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]
                         )
    end
  end


  def self.new_with_session(params, session)
    super.tap do |model|
      if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
        model.email = data["email"] if model.email.blank?
      end
    end
  end
end

【问题讨论】:

  • 您是否在模型中实现了find_for_facebook_oauth 方法?可以展示一下吗?
  • 我确实添加了...我正在浏览omniauth wiki...我现在将发布
  • 任何建议将不胜感激

标签: ruby-on-rails


【解决方案1】:

在找到模型的情况下,您的 find_for_facebook_oauth 方法会隐式返回 nil。如果找到模型,则应显式返回它。

def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
  model = Model.where(:provider => auth.provider, :uid => auth.uid).first
  return model if model
  model = Model.create(name:auth.extra.raw_info.name,
                         provider:auth.provider,
                         uid:auth.uid,
                         email:auth.info.email,
                         password:Devise.friendly_token[0,20]
                         )
end

【讨论】:

  • 在旁注中,这是该方法的一个坏名字,因为它所做的不仅仅是寻找一些东西。 find_or_create_for_facebook_oauth 会更有意义
  • 返回模型给你一个语法错误?你确定你写对了吗?
  • 我刚刚复制并粘贴了你的内容
  • /Users/rickyahn/Sites/abatman-site/app/models/model.rb:32:语法错误,意外的keyword_end,期待$end
  • @user1502223 试试这个:“谢谢,成功了!”。请为 youtube 保留所有大写内容。
【解决方案2】:
def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
  model = Model.where(:provider => auth.provider, :uid => auth.uid).first
  unless model
  model = Model.create(name:auth.extra.raw_info.name,
                     provider:auth.provider,
                     uid:auth.uid,
                     email:auth.info.email,
                     password:Devise.friendly_token[0,20]
                     )
  end
  model #Add this here
end

【讨论】:

  • 你能解释一下你的答案吗?为什么会这样?
  • 我是 Rails 的新手,所以我的推理可能是错误的,但我相信 unless 返回 nil 如果 model 不是 nil,当你想要什么要返回的是model。 Ruby 返回它评估的最后一个东西,因此在末尾添加 model 可确保 Ruby 返回它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-24
  • 2013-11-14
  • 2013-01-14
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多