2011-06-25 17 views
0

Railshasts#235と#236に従って、omniauthでユーザー認証を作成するように設定しました。 http://railscasts.com/episodes/235-omniauth-part-1 http://railscasts.com/episodes/236-omniauth-part-2Rails 3:認証が作成されたときのユーザー属性の更新

私は2つのブールと呼ばれるユーザー・モデルの属性があります。facebok_shareと:twitter_share私はときに新しいをtrueに設定したいです認証が作成されます。

私は新しいユーザーを作成するときにこれは私のために働いていますが、既存のユーザーが認証を追加すると真に更新するブール値を取得できません。

apply_omniauth(omniauth)を呼び出すと、ユーザーモデルでself.facebook_share = trueまたはself.twitter_share = trueが設定されます。

私はapply_shareという新しいメソッドを追加しようとしました。これはプロバイダによってブール値が変化し、current_user.apply_share(omniauth)を呼び出そうとしていますが、データベースで何も起こっていません。

私は間違っていますか?ありがとう!私はあなたが実際にCURRENT_USERを保存することはありません信じて

##の認証コントローラ

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'], 
    :uid => omniauth['uid'], 
    :token => (omniauth['credentials']['token'] rescue nil), 
    :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 

答えて

2

。あなたの属性をtrueに設定し、リダイレクトします。

current_user.apply_share(omniauth) 
current_user.save 

とそれはそれを修正するかどうかを確認:関連付けは役に立つことしようとすると、CURRENT_USER、認証

試してみるだけの新しいインスタンスを更新していない、認証モデルに保存されているので、レールれます。今の場合は、代わりにコールバックを使用することを強くお勧めします。ここを見てみましょう:関連のコールバックについて

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 
+0

current_user.saveを呼び出すことはできますが、私はbefore_add呼び出しでアイデアを設定しようとしましたが、動作させることができません。私は認証プロバイダが 'facebook'か 'twitter'であるかどうかを区別する必要があるので、これを試してみましたが、それは動作しません。場合 'Facebookは' self.facebook_share = trueのときに 'さえずり' self.twitter_share =真 端self.save 端DEF apply_share(認証) 場合認証[ 'プロバイダ'](また構文で上記貼り付け) –

+0

認証の代わりにauthentication.providerを使用しよう[provider] – Kelend

+0

ありがとうございます。 –

1

あなたは*_share属性を設定した後Userオブジェクトに#saveを呼び出す必要があります。 has_manyコレクションに新しい項目を追加する

は自動的コレクションアイテムを保存しますが、親(belongs_to)の保存操作をトリガしません。

関連する問題