0

我使用Stripe創建了訂閱服務。但是,一切正常,當我銷燬/創建一個訂閱,並通過在訂閱模型中使用after_create或after_destroy更新用戶時,它會記錄當前用戶。訂閱被破壞後退出

我有一個基本的身份驗證系統,就像Michael Hartl的Ruby on Rails Tutorial一樣。基本上,記憶令牌存儲在cookie中。

我的after_create & after_destroy在我的訂閱模型調用保存在我的用戶模型當然火保存回調。這意味着保存用戶將始終使記憶令牌無效。是否有解決辦法,以免發生這種情況?

看着日誌,你可以看到正在生成after_destroy的remember_token被調用,然後變得無效。

模型

SUBSCRIPTION MODEL 

class Subscription < ActiveRecord::Base 
    attr_accessible :paypal_customer_token, :paypal_recurring_profile_token, :plan_id, :name, 
        :user_id, :email, :paypal_payment_token, :stripe_customer_token, 
        :stripe_card_token 

    attr_accessor :paypal_payment_token, :stripe_card_token 

    belongs_to :plan 
    belongs_to :user 

    ###used to update the user 
    after_create do 

    ###something happens when the user is updated that logs him out. 
    user.update_attribute(:subscribed, true) unless self.user.subscribed 
    end 

    after_destroy do 
    user.update_attribute(:subscribed, false) if user.subscribed == true 
    end 


end 


USER MODEL 

class User < ActiveRecord::Base 
    attr_accessible :name, :email, :password, :password_confirmation, :subscribed 

    has_secure_password 

    ###This updates my remember_token when the subscription model updates the User 
    before_save :create_remember_token 

    has_one :subscription, :dependent => :destroy 

    private 

    def create_remember_token 
     self.remember_token = SecureRandom.urlsafe_base64 
    end 

end 

控制器

class SubscriptionsController < ApplicationController 

    respond_to :html, :js 

    def create 
    @subscription = Subscription.new(params[:subscription]) 
    if @subscription.save_with_payment 
     redirect_to @subscription, :success => "Thank you for subscribing!" 
    else 
     render :new 
    end 
    end 

    def destroy 
    @subscription = current_user.subscription 
    @subscription.cancel_monthly_subscription 
    if current_user.subscription.destroy 
     flash[:success] = 'Your Subscription was Succesfully Cancelled.' 
     redirect_to root_path 
    end 
    end 

    private 

    def signed_in_user 
     unless signed_in? 
     store_location 
     redirect_to (root_path), notice: "Please sign in." 
     end 
    end 

end 

class UsersController < ApplicationController 
    before_filter :signed_in_user, only: [:update, :edit, :account] 
    before_filter :correct_user, only: [:edit, :update, :account] 

    respond_to :html, :js 

    def edit 
    @user = User.find(current_user.id) 
    end 

    def account 
    @title = "Account" 
    @user = User.find(current_user.id) 
    end 

    def update 
    @user = User.find(current_user.id) 
    if @user.update_attributes(params[:user]) 
     flash[:success] = "Profile updated" 
     sign_in @user 
     redirect_to root_url 
    else 
     error_messages = @user.errors.messages 
     @user = User.find_by_username(params[:id]) 
     @user.errors.messages.merge!(error_messages) 
     if URI(request.referer).path == edit_user_path 
     render 'edit' 
     else 
     render 'account' 
     end 
    end 
    end 

    private 

    def signed_in_user 
     unless signed_in? 
     store_location 
     redirect_to (root_path), notice: "Please sign in." 
     end 
    end 

    def correct_user 
     @user = User.find_by_username(params[:id]) 
     redirect_to(root_path) unless current_user?(@user) 
    end 

end 

日誌

###Is there a reason why the remember token changes at some point, 
could that be the problem? 

Processing by SubscriptionsController#destroy as HTML 

Parameters: {"authenticity_token"=>"aSIR3K3STsdC1vfOKqLZ0Hae28wkbk8TD1Eab5LXzHY=", "id"=>"29"} 
User Load (0.9ms) SELECT "users".* FROM "users" 
WHERE "users"."remember_token" = '-jhzlnlPqy6-okkbZRoyrg' LIMIT 1 

Subscription Load (1.0ms) SELECT "subscriptions".* FROM "subscriptions" 
WHERE "subscriptions"."user_id" = 1 LIMIT 1 

Subscription Exists (0.6ms) SELECT 1 AS one FROM "subscriptions" 
WHERE ("subscriptions"."user_id" = 1 AND "subscriptions"."id" != 29) LIMIT 1 

(0.2ms) BEGIN 
SQL (0.4ms) DELETE FROM "subscriptions" WHERE "subscriptions"."id" = $1 [["id", 29]] 
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 

(1.2ms) UPDATE "users" SET "subscribed" = 'f', 
"remember_token" = 'WedwAYLkPPUGrwlHLECDTA', "updated_at" = '2014-03-01 00:43:24.696602' 
WHERE "users"."id" = 1 

[paperclip] Saving attachments. 
    PgSearch::Document Load (1.8ms) SELECT "pg_search_documents".* 
    FROM "pg_search_documents" WHERE "pg_search_documents"."searchable_id" = 1 
    AND "pg_search_documents"."searchable_type" = 'User' LIMIT 1 
    User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1 
    (1.0ms) COMMIT 

Redirected to http://0.0.0.0:3000/ 
Completed 302 Found in 2307ms (ActiveRecord: 8.5ms) 



Started GET "/" for 127.0.0.1 at 2014-02-28 16:43:24 -0800 
Processing by StaticPagesController#home as HTML 

    User Load (0.8ms) SELECT "users".* FROM "users" 
    WHERE "users"."remember_token" = '-jhzlnlPqy6-okkbZRoyrg' LIMIT 1 

    CACHE (0.0ms) SELECT "users".* FROM "users" 
    WHERE "users"."remember_token" = '-jhzlnlPqy6-okkbZRoyrg' LIMIT 1 

    Rendered shared/_error_messages.html.erb (0.1ms) 
    Rendered shared/_error_messages.html.erb (0.0ms) 
    Rendered sessions/_new.html.erb (3.5ms) 
    Rendered static_pages/home.html.erb within layouts/application (18.1ms) 
    Rendered layouts/_shim.html.erb (0.1ms) 

    CACHE (0.0ms) SELECT "users".* FROM "users" 
    WHERE "users"."remember_token" = '-jhzlnlPqy6-okkbZRoyrg' LIMIT 1 

    Rendered layouts/_navigation_links.html.erb (2.0ms) 
    Rendered layouts/_navigation.html.erb (4.1ms) 

    CACHE (0.0ms) SELECT "users".* FROM "users" 
    WHERE "users"."remember_token" = '-jhzlnlPqy6-okkbZRoyrg' LIMIT 1 

    Rendered layouts/_footer.html.erb (3.5ms) 
    Completed 200 OK in 161ms (Views: 157.3ms | ActiveRecord: 0.8ms) 
+0

您是否使用任何寶石來管理您的身份驗證? –

+0

不,我從頭開始使用邁克爾哈特爾的鐵軌教程。我已經用用戶模型更新了我的代碼。 –

+2

如果您自己編寫身份驗證,任何人都很難告訴您爲什麼要退出身份驗證。如果你正在使用像設計其他人可以提供的輸入。我建議你開始調試你的驗證代碼,試圖確定你沒有登錄的原因(你的應用使用302重定向進行響應)。 –

回答

1

在參考@Pierre Pretorius的評論,標誌出發生的原因是怎麼一回事,因爲你要替換的remember token或者更改數據以在會話之間創建不匹配個持久性數據

我沒有讀Hartl的教程,但如果您的應用程序退出後用戶是否remember_token改變,你需要確保它仍然是相同的:


Conditional callbacks

#app/models/user.rb 
Class User < ActiveRecord::Base 
    before_save :create_remember_token, unless: :subscription? 

    def subscription? 
     subscribed == true? 
     #could just use "subscribed" 
    end 
end 
+0

太棒了,謝謝! :),我也想使用update_column方法,因爲它會根據這個跳過回調。 http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column –