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: Parked at Loopia