Adding Logic to first rails app in case of error from 2nd rails app

Hi All,

I have been following the latest advanced rails recipe tutorial,
“handing recurring credit card payments” and its excellent. The code
works great if there are no problems with the user creation, credit
card creation or purchase creation. The problem is I want to add some
validation and logic inc ase something happens along the way. Right
now if the credit card or purchase create fails on the card_server, my
rails app returns the following error, otherwise the creation works
great. How can I clean up my code to handle errors from my card_server
better?

Thanks!

You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.status=

My Rails App Controller Method
def signup_unlimited_create
@user = User.new(params[:user])
@user.account_type = “Unlimited”
@user.login = @user.email

#create credit_card entry
if @user.save
    # store credit card
  @cc = CreditCard.create(:first_name => @user.first_name,
  :last_name => @user.last_name,
  :number => params[:card_number],
  :month => params[:card_expiration_month],
  :year => params[:card_expiration_year],
  :brand => params[:card_type])
else
  redirect_to :controller => 'account', :action => 'index'
end

if @cc.status = "created"
  @user.credit_card_id = @cc.id
  #purchase credit card
  @pp = Purchase.create(
  :amount => 911.95,
  :description => "Initial Payment",
  :order => "1100030",
  :credit_card_id => @cc.id)
  self.current_user = @user

   if @pp.status = "created"
           #create invoice
      @invoice = Invoice.new(params[:invoice])
      @invoice.due_date = Time.now + 30.days
      @invoice.generated_date = Time.now
      @invoice.status = "Due"
      @invoice.user_id = @user.id
      @invoice.save

      redirect_to :controller => 'account', :action => 'index'
  else
    redirect_to :controller => 'account', :action =>

‘signup_unlimited’
end
end
end

My Rails App Card Server Controller’s look something like this

class PurchasesController < ApplicationController

def create
@purchase = Purchase.new(params[:purchase])

respond_to do |format|
  if @purchase.save
    format.xml { render :xml => @purchase,
                        :status => :created,
                        :location => @purchase }
  else
    format.xml { render :xml => @purchase.errors,
                        :status => :unprocessable_entity }
  end
end

end
end

class CreditCardsController < ApplicationController

def create
@credit_card = CreditCard.new(params[:credit_card])

respond_to do |format|
  if @credit_card.save
    format.xml { render :xml => @credit_card,
                        :status => :created,
                        :location => @credit_card }
  else
    format.xml { render :xml => @credit_card.errors,
                        :status => :unprocessable_entity }
  end
end

end
end

U can put all the database transactions in a transaction block.
begin
database transactions of creating any records and all
rescue
handle the errors gracefully over here
end

Also in your code you should always check for the variable to be not
nil, before accessing any information from it.

Hope it helps.

Could I use rescue for the following scenario?

Credit Card is created if the user is saved, like below. The problem
is, the user is still getting saved even if the credit card is not
being saved. Would I use rescue in a case like that?

Thanks!

def signup_unlimited
@user = User.new
end

def signup_unlimited_create
@user = User.new(params[:user])
@user.account_type = “Unlimited”
@user.login = @user.email
#create credit_card entry
if @user.save
self.current_user = @user
@cc = CreditCard.create(:first_name => @user.first_name,
:last_name => @user.last_name,
:number => params[:card_number],
:month => params[:card_expiration_month],
:year => params[:card_expiration_year],
:brand => params[:card_type])
@user.credit_card_id = @cc.id

   if @user.credit_card_id == nil
     flash[:notice] = "problem creating the credit card"
     render :action => 'signup_unlimited'
   end

   if @user.credit_card_id != nil
     flash[:notice] = "congrats, you created an account and we

charged your card"
render :action => ‘index’
end

 else
   flash[:notice] = "problem creating the user"
   render :action => 'signup_unlimited'
 end

end

Pastie: http://pastie.caboo.se/160574