0

私は単純な会計アプリケーションを構築しています。トランザクションには多くのエントリがあり、各エントリは 1 つのトランザクションに属します。各エントリは、借方エントリまたは貸方エントリのいずれかです。すべての借方の「金額」フィールドの合計は、各トランザクションのすべての貸方の合計と等しくなければなりません。したがって、私のトランザクション モデルには次のようなものがあります。

トランザクション.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 

しかし、これはうまくいきません。エラーはスローされませんが、条件が満たされない場合でも、トランザクションとすべてのエントリがデータベースに保存されるのを停止しません。エントリ モデルの「金額」が、entries_attributes の params ハッシュにあるという事実に関係があるのではないかと考えました。そうですか?その場合、上記のコードを書き直して、トランザクションが保存される前に、entries_attributes params ハッシュの金額を合計するにはどうすればよいですか?

ありがとう。

アップデート:

私もこれを試しましたが、どちらもうまくいかなかったようです:

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

更新 2:

最終的に、検証をコントローラーに移動することで機能するようになりました。しかし、検証を 1 か所に保持できるように、これをモデルに戻すにはどうすればよいでしょうか?

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
4

1 に答える 1

0

検証方法の問題。データベースに 2 つの合計を要求すると、新しいエントリがまだデータベースに存在しないため、検証がうまくいきます。entry_attributes のみをチェックする必要があります (仮定できるので、データベースではすべて問題ありません)。

于 2012-12-22T23:29:12.807 に答える