我正在对Rails应用程序进行最后润色,昨天一切正常,(大部分仍然是)。但是现在,当我尝试使用Facebook登录时,我收到错误NoMethodError undefined method persisted? for nil:NilClass
我没有更改omniauth_callbacks_controller或用户模型中的任何代码,所以我不明白为什么会突然发生这种情况
这是omniauth_callbacks_controller
中的代码def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
@user = User.from_omniauth(env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
else
session["devise.#{provider}_data"] = env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
[:twitter, :facebook].each do |provider|
provides_callback_for provider
end
在User.rb中
def self.from_omniauth(auth)
identity = Identity.where(provider: auth.provider, uid: auth.uid).first_or_create do |identity|
if identity.user == nil
user = User.new
user.email = auth.info.email || "#{auth.uid}@#{auth.provider}.generated"
user.password = Devise.friendly_token[0,20]
user.provider = auth.provider
if auth.provider == "facebook"
user.name = auth.info.name
user.username = "FacebookUser" + (1 + rand(1000)).to_s
elsif auth.provider == "twitter"
user.name = auth.info.name
user.username = auth.info.nickname
end
end
identity.user = user
end
identity.access_token = auth['credentials']['token']
identity.refresh_token = auth['credentials']['refresh_token']
identity.expires_at = auth['credentials']['expires_at']
identity.timezone = auth['info']['timezone']
identity.save
identity.user
end
我无法弄清楚为什么它在昨天工作,但现在不是。什么也没有变!我仍在使用相同的URL访问它,我没有搞砸Facebook上的API设置或devise.rb。
答案 0 :(得分:0)
问题是identity.user是nill。可能会发生这种情况,因为用户模型中的用户无效(未保存在db中),未通过验证
我认为问题可以在user.email = auth.info.email || "#{auth.uid}@#{auth.provider}.generated"
- 错误的电子邮件类型。您可以在创建用户的块中添加puts user.errors
之类的内容。
我也不明白为什么你需要一个模特 - 身份。更容易向用户模型添加字段
这是我的代码(它的工作):
def self.from_omniauth(auth)
email = auth.info.email
user = User.find_by(email: email) if email
user ||= User.create do |user|
user.provider= auth.provider
user.uid= auth.uid
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.name = auth.info.name
user.email ||= "#{auth.uid}_#{auth.uid}@email.com"
end
end