2011-04-13 42 views
0

我正在使用facebooker2(Rails 2.3和RESTFUlL身份驗證)進行facebook連接功能。在我的控制器中,我使用這個動作:Facebooker2如何保存一個新的註冊?

def create_facebook_user 
    if current_facebook_user 
     @user = User.find_by_fb_user_id(current_facebook_user.id.to_i) 
    end 
    if @user.blank? 
     @facebook_user = current_facebook_user.fetch 

     @user = User.new :login => @facebook_user.email, :email => @facebook_user.email, :name => @facebook_user.name 
     @user.fb_user_id = @facebook_user.id.to_i 
     @user.state = "active" 

     if @user.save(:validate=> false) 
     @user.profile = Profile.create(:benefactor_id => nil, :benefactor_invites => Setting.find_by_identifier("benefactor_invites").value.to_i) 
     redirect_to :controller => "profiles", :action => "show", :id => @user.profile.id 
     else 
     render "new" 
     end 
    elsif @user.fb_user_id.nil? 
     @user.update_attribute :fb_user_id, current_facebook_user.id 
     redirect_to :controller => "dashboard", :url => "index" 
    else 
     redirect_to :controller => "dashboard", :url => "index" 
    end 

然後我的問題是給用戶分配狀態。當用戶使用save方法@ user.save(:validate => false)時,它不會「跳過」驗證器。另外我修改了一個RESTFul認證模塊「ByPassword」的方法password_required,但保存方法返回false。

我後我的代碼

Controller 

    class UsersController < ApplicationController 
     skip_before_filter :verify_authenticity_token, :only => :create 

     before_filter :find_user, 
        :only => [:profile, 
           :destroy, 
           :edit_password, :update_password, 
           :edit_email, :update_email] 

     layout 'application' 
     def create_facebook_user 
     if current_facebook_user 
      @user = User.find_by_fb_user_id(current_facebook_user.id.to_i) 
     end 
     if @user.blank? 
      @facebook_user = current_facebook_user.fetch 

      @user = User.new :login => @facebook_user.email, :email => @facebook_user.email, :name => @facebook_user.name 
      @user.fb_user_id = @facebook_user.id.to_i 
      @user.state = "active" 

      if @user.save(:validate=> false) 
      @user.profile = Profile.create(:benefactor_id => nil, :benefactor_invites => Setting.find_by_identifier("benefactor_invites").value.to_i) 
      redirect_to :controller => "profiles", :action => "show", :id => @user.profile.id 
      else 
      render "new" 
      end 
     elsif @user.fb_user_id.nil? 
      @user.update_attribute :fb_user_id, current_facebook_user.id 
      redirect_to :controller => "dashboard", :url => "index" 
     else 
      redirect_to :controller => "dashboard", :url => "index" 
     end 
     end 

end 

視圖(重要片段)

Øingresa CON Facebook連接 <%= fb_login_and_redirect( 「/用戶/ create_facebook_user」)%> <% #= fb_login_and_redirect('/ users/link_user_accounts',:perms =>'email,user_birthday')%> <%#= fb_login_button(「window.location ='/ users/link_user_accounts'「)%>

用戶模型

require 'digest/sha1' 

class User < ActiveRecord::Base 
    include Authentication 
    include Authentication::ByPassword 
    include Authentication::ByCookieToken 
    include Authorization::AasmRoles 

... 
end 

ByPassword模塊

module Authentication 
    module ByPassword 

    # Stuff directives into including module 
    def self.included(recipient) 
     recipient.extend(ModelClassMethods) 
     recipient.class_eval do 
     include ModelInstanceMethods 

     # Virtual attribute for the unencrypted password 
     attr_accessor :password 
     validates_presence_of :password, :message => :"user.password.blank", :if => :password_required? 
     validates_presence_of :password_confirmation, :message => :"user.password_confirmation.blank", :if => :password_required? 
     validates_confirmation_of :password, :message => :"user.password.confirmation", :if => :password_required? 
     validates_length_of :password, :within => 5..40, :message => :"user.password.too_short", :if => :password_required? 
     before_save :encrypt_password 

     end 
    end 

    # #included directives 

    # 
    # Class Methods 
    # 
    module ModelClassMethods 
     # This provides a modest increased defense against a dictionary attack if 
     # your db were ever compromised, but will invalidate existing passwords. 
     # See the README and the file config/initializers/site_keys.rb 
     # 
     # It may not be obvious, but if you set REST_AUTH_SITE_KEY to nil and 
     # REST_AUTH_DIGEST_STRETCHES to 1 you'll have backwards compatibility with 
     # older versions of restful-authentication. 
     def password_digest(password, salt) 
     digest = REST_AUTH_SITE_KEY 
     REST_AUTH_DIGEST_STRETCHES.times do 
      digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY) 
     end 
     digest 
     end 
    end # class methods 

    # 
    # Instance Methods 
    # 
    module ModelInstanceMethods 

     # Encrypts the password with the user salt 
     def encrypt(password) 
     self.class.password_digest(password, salt) 
     end 

     def authenticated?(password) 
     crypted_password == encrypt(password) 
     end 

     # before filter 
     def encrypt_password 
     return if password.blank? 
     self.salt = self.class.make_token if new_record? 
     self.crypted_password = encrypt(password) 
     end 

     def password_required? 
     if fb_user_id.blank? 
      crypted_password.blank? || !password.blank? 
     else 
      return false 
     end 
     end 

     def has_fb_user_id? 
     fb_user_id.nil? 
     end 
    end # instance methods 
    end 
end 
+0

你*有*使用Facebooker2嗎?我發現omniauth和考拉的組合很好。只是問,因爲我有可能有解決方案,如果你沒有使用Facebooker2的原因(例如在一個項目/團隊已經使用它)。 – justinxreese 2011-04-13 17:14:00

回答

0

首先我使用save_with_validations(ActiveRecord的假)方法,然後我用正常保存方法