我正在使用Stripe来处理付款。我使用事务块的原因是为了确保以下成功或根本没有:
我无法工作的一件事是rescue
块。我故意给Stripe一张无效的信用卡以使交易失败。但是,当它失败时,它不会render :new
def create
manager = current_session.manager
plan = Plan.find params[:plan_id]
Payment.transaction do
Payment.create(
plan_id: params[:plan_id],
management_id: current_session.management.id
)
begin
stripe_customer = Stripe::Customer.retrieve(manager.payment_provider_customer_id) if manager.try(:payment_provider_customer_id).present?
if stripe_customer.present?
# do something here
else
stripe_customer = Stripe::Customer.create(
email: manager.email,
metadata: {
manager_id: manager.id
}
)
stripe_customer.cards.create(card: 'zzzzzzzzzzzz')
stripe_customer.subscriptions.create(plan: plan.payment_provider_plan_id)
end
rescue => error
# If any of the Stripe requests fail, then we must also rollback the payment transaction
puts "Error: #{error}"
raise ActiveRecord::Rollback
render :new
else
redirect_to root_path, notice: 'Thank you. Your payment is being processed.'
end
end
end
我得到的错误是:
Missing template dashboard/payments/create, dashboard/application/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee, :slim]}
答案 0 :(得分:1)
问题是你提出了ActiveRecord :: Rollback异常,然后尝试渲染:new
。异常引发后的代码永远不会执行。我建议你分开管理事务的方法,如下所示:
def create
your_processing_transaction_method
redirect_to root_path, notice: 'Thank you. Your payment is being processed.'
rescue ActiveRecord::Rollback
render :new and return
end
private
def your_processing_transaction_method
manager = current_session.manager
plan = Plan.find params[:plan_id]
Payment.transaction do
Payment.create(
plan_id: params[:plan_id],
management_id: current_session.management.id
)
begin
stripe_customer = Stripe::Customer.retrieve(manager.payment_provider_customer_id) if manager.try(:payment_provider_customer_id).present?
if stripe_customer.present?
# do something here
else
stripe_customer = Stripe::Customer.create(
email: manager.email,
metadata: {
manager_id: manager.id
}
)
stripe_customer.cards.create(card: 'zzzzzzzzzzzz')
stripe_customer.subscriptions.create(plan: plan.payment_provider_plan_id)
end
rescue => error
raise ActiveRecord::Rollback
end
end
end
请记住,这显然不是最好的设计决策(即在控制器中处理所有这类事务处理和业务代码)。控制器应该只负责接收请求,将其交给域模型并根据域的响应返回响应。
将此私有方法提取到服务类是一种更好的方法,但我认为它可以帮助处理事务/呈现问题。
答案 1 :(得分:0)
问题是你在打电话
render :new
你需要
render :new and return
由于没有返回,代码在渲染后继续,然后隐式渲染创建模板