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