如何解决Rails 3:创建身份验证时更新用户属性
| 我按照Railscasts#235和#236进行设置,以使用omniauth创建用户身份验证。 http://railscasts.com/episodes/235-omniauth-part-1 http://railscasts.com/episodes/236-omniauth-part-2 我在用户模型上有两个布尔属性::facebok_share和:twitter_share,当创建新的身份验证时,我想将其设置为true。 创建新用户时,我可以使用该功能,但是如果现有用户添加了身份验证,则无法获取布尔值来更新为true。 调用apply_omniauth(omniauth)时,它将在我的用户模型中设置self.facebook_share = true或self.twitter_share = true。 我试图添加一个名为apply_share的新方法,该方法根据提供程序来更改布尔值,并且我试图调用current_user.apply_share(omniauth),但数据库中没有任何反应。 我究竟做错了什么?谢谢! ##身份验证控制器class AuthenticationsController < ApplicationController
def index
@title = \"Authentications\"
@authentications = current_user.authentications if current_user
end
def create
# creates omniauth hash and looks for an prevIoUsly established authentication
omniauth = request.env[\"omniauth.auth\"]
authentication = Authentication.find_by_provider_and_uid(omniauth[\'provider\'],omniauth[\'uid\'])
# if prevIoUs authentication found,sign in user
if authentication
flash[:notice] = \"Signed in successfully\"
sign_in_and_redirect(:user,authentication.user)
# for users already signed in (current_user),create a new authentication for the user
elsif current_user
current_user.apply_share(omniauth)
current_user.authentications.create(:provider => omniauth[\'provider\'],:uid => omniauth[\'uid\'],:token => (omniauth[\'credentials\'][\'token\'] rescue nil),:secret => (omniauth[\'credentials\'][\'secret\'] rescue nil))
flash[:notice] = \"authentications successful\"
redirect_to authentications_url
# new user is created and authentications are built through apply_omniauth(omniauth)
else
user = User.new
user.apply_omniauth(omniauth)
if user.save
flash[:notice] = \"Signed in successfully\"
sign_in_and_redirect(:user,user)
# if validations fail to save user,redirects to new user registration page
# new twitter authentications redirect so user can enter their password
else
session[:omniauth] = omniauth
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
## user model
# set share booleans to true depending on \'provider\' type
def apply_share(omniauth)
case omniauth[\'provider\']
when \'facebook\'
self.facebook_share = true
when \'twitter\'
self.twitter_share = true
end
end
# from authentications controller,new user split into type of provider
def apply_omniauth(omniauth)
case omniauth[\'provider\']
when \'facebook\'
self.apply_facebook(omniauth)
when \'twitter\'
self.apply_twitter(omniauth)
end
# builds authentication with provider,uid,token,and secret
authentications.build(hash_from_omniauth(omniauth))
end
protected
# sets new user attributes from facebook
def apply_facebook(omniauth)
self.name = omniauth[\'user_info\'][\'name\']
self.email = omniauth[\'user_info\'][\'email\'] if email.blank?
self.facebook_share = true
end
# sets new user attributes from twitter
def apply_twitter(omniauth)
if (extra = omniauth[\'extra\'][\'user_hash\'] rescue false)
# Example fetching extra data. Needs migration to User model:
# self.firstname = (extra[\'name\'] rescue \'\')
self.name = (extra[\'name\'] rescue \'\')
self.bio = (extra[\'description\'] rescue \'\')
end
self.twitter_share = true
end
# set authentication attributes to those from \'omniauth\' hash
def hash_from_omniauth(omniauth)
{
:provider => omniauth[\'provider\'],:secret => (omniauth[\'credentials\'][\'secret\'] rescue nil)
}
end
end
## new methid with :before add => :apply_share
def apply_share(authentication)
case authentication[\'provider\']
when \'facebook\'
self.facebook_share = true
when \'twitter\'
self.twitter_share = true
end
self.save
end
解决方法
我相信您从未真正保存过current_user。因此,将属性设置为true,然后重定向。关联存储在身份验证模型中,因此,Rails试图提供帮助,不会更新current_user,而只是更新身份验证的新实例
尝试:
current_user.apply_share(omniauth)
current_user.save
看看是否能解决。现在如果可以,我强烈建议您改用回调。在这里看看:
http://guides.rubyonrails.org/association_basics.html
第4.5节关于关联回调。您可以在has_many身份验证关联上执行before_add回调,以从控制器中删除该代码,因为该代码变得非常肿。
class User < ActiveRecord::Base
has_many :authentications,:before_add => :apply_share
def apply_share(authentication)
#update attributes
#save model
end
end
, 设置*_share
属性后,需要在User
对象上调用#save
。
将新项目添加到“ 6”集合中会自动保存该集合项目,但不会触发父项(“ 7”)上的保存操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。