Question

In my sub-ledger accounting rails app I have a funds model

class Fund < ActiveRecord::Base
    belongs_to :agency
    has_many :gl_accounts

    accepts_nested_attributes_for :gl_accounts

    attr_accessible :name, :agency_id, :fund, :user_stamp, :active
    attr_accessible :gl_accounts_attributes

and a gl_accounts model

class GlAccount < ActiveRecord::Base
    belongs_to :agency
    belongs_to :fund
    has_many :class_sessions
    has_many :facilities

    validates :agency_id, :fund_id, :name, :gl_account_number, :active, :user_stamp, :account_type, :presence => true
    validates_uniqueness_of :account_type, :scope => :fund_id, :if => :unique_account_type

    attr_accessible :agency_id, :fund_id, :name, :gl_account_number, :active, :user_stamp, :account_type

    def unique_account_type
        [3,4,6,7,8].include? account_type
    end

When a new fund is created there are 5 gl_accounts that must be created at the same time so I am using fields_for to create the 5 new records in the gl_account model when the new record is created for fund. It all seems to work OK until I submit the form and I get an error saying that "Gl accounts fund cannot be blank."

There is no "fund" attribute on the gl_accounts model. I thought that maybe rails was dropping the "_id" part (since there is a fund_id foreign key field) but I was under the understanding that using nested models and fields_for automatically added the proper value in the fund_id field (the foreign key of the gl_account model). But even if I add a hidden field in the form with a value for fund_id I still get the error saying that "fund" cannot be blank.

So, maybe rails is trying to tell me I have something else wrong?

Here are the params:

{"utf8"=>"✓",
 "authenticity_token"=>"MNWLFOnLOE+ZRsUf9mogf2cq/TeQ+mxtrdaVu3bEgpc=",
 "fund"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "name"=>"Junk",
 "fund"=>"44",
 "active"=>"1",
 "gl_accounts_attributes"=>{"0"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "account_type"=>"6",
 "name"=>"Cash Account",
 "active"=>"1",
 "fund_id"=>"1",
 "gl_account_number"=>"44-498-965-789"},
 "1"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "account_type"=>"7",
 "name"=>"Credit Card Account",
 "active"=>"1",
 "fund_id"=>"1",
 "gl_account_number"=>"44-498-965-163"},
 "2"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "account_type"=>"3",
 "name"=>"Customer Account Balances",
 "active"=>"1",
 "fund_id"=>"1",
 "gl_account_number"=>"44-498-965-254"},
 "3"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "account_type"=>"8",
 "name"=>"Refunds Pending Account",
 "active"=>"1",
 "fund_id"=>"1",
 "gl_account_number"=>"44-498-965-456"},
 "4"=>{"agency_id"=>"1",
 "user_stamp"=>"6",
 "account_type"=>"4",
 "name"=>"Deferred Revenue Account",
 "active"=>"1",
 "fund_id"=>"1",
 "gl_account_number"=>"44-498-965-159"}}},
 "commit"=>"Add New Fund"}
Was it helpful?

Solution

Try removing fund_id from the presence true validation in GlAccount class.

validates :agency_id, :name, :gl_account_number, :active, :user_stamp, :account_type, :presence => true

And also don't add fund_id as hidden field because , you are right, 'fields_for' will automatically take care of that but that will happen after validations.

So you don't need fund_id to be validated for presence.

Update

Also to ensure that fund_id is never null you can put a constraint in database table. Create a migration with the following code.

change_column :gl_accounts, :fund_id, :integer, :null => false

Update 2

To ensure that fund is there you need to check for presence of fund not fund_id.

validates :fund, :presence => true

And for this to work you need to declare your associations with 'inverse_of' like below.

class Fund < ActiveRecord::Base
  has_many :gl_accounts, inverse_of: :fund
  accepts_nested_attributes_for :gl_accounts
end

class GlAccount < ActiveRecord::Base
  belongs_to :fund, inverse_of: :gl_accounts
  validates_presence_of :fund
end

For more details please refer this guide. http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#label-Validating+the+presence+of+a+parent+model

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top