我使用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)
答案 0 :(得分:1)
在参考@Pierre Pretorius
的评论时,退出的原因是因为您正在替换remember token
,或者更改数据以在您的会话和广告之间造成不匹配。持久数据
我没有阅读过Hartl教程,但是如果您的应用在remember_token
发生变化时签署了用户,则需要确保它保持不变:
#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