订阅被销毁后退出

时间:2014-03-01 00:52:07

标签: ruby-on-rails ruby ruby-on-rails-3 authentication stripe-payments

我使用Stripe创建了订阅服务。但是,当我销毁/创建订阅并在订阅模型中使用after_create或after_destroy更新User时,一切正常,它会将当前用户记录下来。

我有一个基本的身份验证系统,就像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

CONTROLLER

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)

1 个答案:

答案 0 :(得分: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