belongs_to causing endless loop on first call to save!


I have a situation I’m hoping someone out there may be able to shed some light on. I have a Rails app (2.1.0 on Ruby 1.8.7) with a wizard-based sign up process, that has recently been changed from storing incremental data in the database to having a medium sized object graph living in the user session until the user completes the entire sign up process (this is a business requirement now). After the user commits all relevant data, I’m now calling save! on the top-level object to save all the rows at once. However, when the call to save! happens–and because I have two objects that have a belongs_to association, each pointing to other in addition to the normal bidirectional association–I end up in an endless validation loop. Funny thing is, when I was incrementally saving the data, this issue never arose–another way to put it, those relationships never caused a problem when saving/retrieving already-existing rows.

In the model tier, I have the following classes defined:

class PrimaryAccount < Account
has_many :payment_methods, :foreign_key => “account_id” #using single table inheritance, which is why foreign key is not “primary_account_id”
belongs_to :current_payment_method, :class_name => “PaymentMethod”, :foreign_key => “current_payment_method_id” #points to same table, so I can have many payment_methods, but also mark as being the current one to bill

class PaymentMethod < ActiveRecord::Base
belongs_to :account #normal bidirectional association

class CreditCard < PaymentMethod

In the controller tier, I have a session object that–on the final step–loads an Account model object based on the current session state, and then calls save! on that model:

class PrimaryAccountUser < User

attr_reader :credit_card

def initialize(service_id)
@credit_card = {} #hash for storing credit card attributes

def persist_to_database
@id =
return account


def add_session_data_to_account(account) #adds the impl-specific things to the account

  card = do |cc|
    cc.account_type = @credit_card[:type]
    cc.account_name = @credit_card[:name]
    cc.account_number = @credit_card[:number]
    cc.cvv = @credit_card[:cvv]
    cc.account_expiration = @credit_card[:expiration]
    cc.address = @credit_card[:address] = @credit_card[:city]
    cc.state = @credit_card[:state] = @credit_card[:zip] = @credit_card[:country] = @credit_card[:phone]

  #strange...this won't populate the account_id on save!
  account.payment_methods << card

  #again, if I don't do this, then the payment_method won't have a populated account_id on save!
  card.account = account
  #doing this causes the endless validation loop
  account.current_payment_method = card

return account


Am I crazy for thinking this ought to work?

Thanks in advance,

Ryan Frith

It just seems way too overengineered to me. When you add a card to the system, just add the card

In the controller, for example:

def create
card =[:card]
card.account_id = session[:user_id] # or or wherever you store the id of the currently logged in user.



No need to do all that account << card stuff because the web is stateless. When it’s saved, you’re going to redirect them, a new request will be made by your user, and the records get queried again. Plus you save a ton of overhead.

just my .02.

Or maybe I’m oversimplifying your situation, but I just like to keep things as simple as possible.

Maybe you didn't see the fine print--I'm saving the entire object
graph at once; there is no session[:user].id or current_user. I
greatly simplified the code for the sake of brevity, but all the
objects get assembled in the final sign-up step from state stored in
the session over many screens (wizard) and then all the objects in the
graph get persisted from the call to the top-level object's save!
method. This was a design decision to not save session state to DB in
between requests for the sign up process. Anyways, the issue may be
related to this one:

Anyone else have any ideas?