2

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"}
2
  • What do your params look like? Commented Aug 17, 2013 at 17:03
  • @snowangel - I went back and included the params in the original post. As you can see, there is a fund_id in the params for each record to be created. Commented Aug 17, 2013 at 17:14

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you. Removing fund_id from the validation allowed it to work. (I only had fund_id in the params as a test anyway) Now it works as planned... except -- now I am nervous because gl_accounts can also be created independently of fund creation and absolutely must have a fund_id or it's a disaster. That's why I had the model validating for presence. So, now I just have to figure out how to ensure presence of fund_id if the gl_account is created in a new/create action directly on the gl_accounts model.
I think, to ensure that the fund_id is never null, the best way is to add a constraint in database. I will update the answer.
Yup, I had already done that. I'll just have to trap for that db error. Plus, I suppose I can use javascript validation in the form to decrease the possibility of it ever arriving at the db level without a fund_id.
@circle1 Here man. Don't worry about java script and all. I have updated the answer for you as well as me.:)
That looks ideal, but it isn't working for me. If I validate presence of :fund, it gives the same error as when I was validating :fund_id. Have you gotten it to work for you?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.