Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing params from nested attributes in a validation
    primarykey
    data
    text
    <p>I'm building a simple accounting application. Transactions have many entries, and each entry belongs to one transaction. Each entry is either a debit or a credit entry. The sum of the 'amounts' field for all the debits must equal the sum of all the credits for each transaction. So in my transaction model, I have the following: </p> <p>Transaction.rb</p> <pre><code>attr_accessible :entries_attributes has_many :entries accepts_nested_attributes_for :entries validate :entries_sum_to_zero private def entries_sum_to_zero errors.add(:base, "Debits and credits must balance.") unless self.entries.where(:entry_type =&gt; 'Credit').sum(:amount) == self.entries.where(:entry_type =&gt; 'Debit').sum(:amount) end </code></pre> <p>But this doesn't work. It doesn't throw an error, but it also doesn't stop the transaction and all of the entries from saving to the database if the condition is not met. I thought it might have to do with the fact that the 'amount' from the entries model is in the params hash for entries_attributes. Is that the case? IF so, how do I rewrite the above code to sum the amounts in the entries_attributes params hash before the transaction is saved?</p> <p>Thanks. </p> <p>UPDATE: </p> <p>I also tried this but it did not seem to work either: </p> <pre><code>before_save :entries_sum_to_zero private def entries_sum_to_zero if self.entries.where(:entry_type =&gt; 'Credit').sum(:amount) != self.entries.where(:entry_type =&gt; 'Debit').sum(:amount) errors.add(:base, "Debits and credits must balance.") return false end end </code></pre> <p>UPDATE 2: </p> <p>I ultimately got it to work by moving the validation into the controller. But how do I move this back into the model so I can keep the validations in one place?</p> <pre><code>def create @company = Company.find(params[:company_id]) @transaction = @company.transactions.new(params[:transaction]) sum_of_debits = 0 sum_of_credits = 0 params[:transaction]['entries_attributes'].each do |k,v| sum_of_debits += v['amount'].to_i if v['entry_type'] == "Debit" sum_of_credits += v['amount'].to_i if v['entry_type'] == "Credit" end if sum_of_credits != sum_of_debits flash[:error] = "Debits and Credits must balance." render 'new' else if @transaction.save flash[:success] = "Transaction added" redirect_to company_path(@company) else render 'new' end end end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload