我正在构建一个简单的会计应用程序。事务有许多条目,每个条目属于一个事务。每个分录要么是借方,要么是贷方。所有借方的"金额"字段的总和必须等于每笔交易的所有贷方的总和。因此,在我的事务模型中,我有以下内容:
Transaction.rb
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 => 'Credit').sum(:amount) == self.entries.where(:entry_type => 'Debit').sum(:amount)
end
但这不起作用。它不会抛出错误,但如果不满足条件,它也不会停止事务和保存到数据库的所有条目。我认为这可能与条目模型中的"金额"在条目属性的参数哈希中有关。是这样吗?如果是这样,我如何重写上面的代码,以便在保存事务之前将entres_attributes参数散列中的金额相加?
谢谢。
更新:我也试过这个,但它似乎也不起作用:
before_save :entries_sum_to_zero
private
def entries_sum_to_zero
if self.entries.where(:entry_type => 'Credit').sum(:amount) != self.entries.where(:entry_type => 'Debit').sum(:amount)
errors.add(:base, "Debits and credits must balance.")
return false
end
end
UPDATE 2:
我最终通过将验证移动到控制器中使其工作。但如何将其移回模型中,以便将验证保存在一个地方呢?
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
验证方法中的问题。您向数据库请求两个和,并且验证进行得很顺利,因为您的新条目还不存在于数据库中。您必须只检查entres_attributes(因为我们可以假设,然后在数据库中一切正常)