Reputation: 427
Using Stripe and want to: 1. check model validation 2. if no errors process card token. 3. If card works then save new record.
Below I have it where it processes card first, then if successful, saves record. Unfortunately that record might fail validation but the card was already charged.
As a hack I have a js validation (that mirrors the model validations) in the view that doesn't allow the form to be submitted until the terms are met.
Tourregistration.rb Controller
def create
token = params[:tourregistration][:stripeToken]
begin
charge = Stripe::Charge.create(
:amount => (params[:tourregistration][:invoice].to_d*100).round,
:currency => "usd",
:source => token,
:description => "Example charge"
)
rescue Stripe::CardError => e
# The card has been declined
redirect_to :back, :notice => "#{e}"
else
@tourregistrations = tourregistration_data.map do |tourregistration_params|
Tourregistration.new(tourregistration_params)
end
@tourregistrations.each(&:save)
if @tourregistrations.all?(&:valid?)
flash[:notice] = 'Sign-up Complete'
redirect_to root_url
else
redirect_to :back, :notice => "Something went wrong. Please fill in all fields."
end
end
end
Tourregistration.rb Model
class Tourregistration < ActiveRecord::Base
belongs_to :patron
belongs_to :tour
has_one :referrer
validates :fname, length: { minimum: 2}
validates :lname, length: { minimum: 2}
validates :email, presence: true
validates :price, presence: true
validates :invoice, presence: true
validates :patron_id, presence: true
validates :tour_id, presence: true
end
Upvotes: 0
Views: 1432
Reputation: 12564
Other than callbacks, you can use a database transaction, for example :
ActiveRecord::Base.transaction do
results = @tourregistrations.map(&:save) # validate and save the records
raise ActiveRecord::Rollback if results.any?{|result| result == false } # rollback the transaction if any registration failed to be saved
payment = charge_card # process the payment
raise ActiveRecord::Rollback unless payment # rollback if payment failed
end
As a side note, this kind of logic is a textbook example for a service object.
Upvotes: 2