I have implemented a Paypoint payment into a project I am working on and in the pass I used a class called by a controller to process the payment and act on the response, now i've redone this to process the payment on the before_create callback so that if the payment fails the transction rolls back and I add an error to the model and now the controller code if just checks if the model is save
old controller code
def create
@model = Model.new(params[:xxx])
if @model.valid?
if PayPointPayment.authorise_payment(@model)
redirect_to new_step
else
开发者_如何学C render :new
else
render :new
end
new controller code
def create
@model = Model.new(params[:xxx])
if @model.save
redirect_to next_step
else
render :new
end
new model code
class Model
before_create :process_payment
def process_payment
if PayPointPayment.authorise_payment(self)
return true
else
<add errors>
return false
end
end
just wondering what the thoughts are on this kind of design is it good or bad or just plain wrong
Rather than performing the payment via before_create
it may make more sense to run the payment as part of validation. It might wind up working identically, but the message it sends to the programmer is that validation is a series of requirements that must be met before the model object can be saved, and before_create
might take care of pre-requisites that need to be performed to allow creating the end model.
Also, if you ever update the model object, it may change the model enough to require revalidation, but before_create
won't catch that.
Compared against your original mechanism, of course, this is probably a huge improvement in almost every respect -- it would allow your model to be used outside of the original controller without giving away product/content to users who haven't paid. (Say, if you expose a SOAP or XMLRPC or email or REST interface that doesn't run through your controller.)
精彩评论