2012-07-19 2 views
1

기록 : 내가 보장 할유효성 검사/어린이 나는이 개 모델이

Invoice has_many :lines 

Line belongs_to :invoice 

을 그 주어진 Invoice 경기 전체에 대한 Line의 합 관련 Invoice.

나는이 시도했다 :

validate :total_amount 
def total_amount 
    inv_id = self.invoice_id 
    target_amount = Invoice.find(inv_id).total 
    total_lines = Line.where(invoice_id: inv_id).sum(:line_value) 

    errors.add(:total, " should be lower or equal to the total amount of the invoice") if total_lines > target_amount 
end 

그러나

  1. 는 새로운 객체 (단지 업데이트) 작동하지 않습니다 체계적에서 오류가 발생하더라도 업데이트가

AssociatedValidator에 관한 질문도 보았습니다.하지만 사용 방법을 파악하지 못했습니다. 그 :(

답변

1

. 대신 방법으로 사용하고 Line 가격에 조정을 더한 방법을 사용하십시오. 그렇지 않으면 데이터베이스에 복제본이 있습니다. 그런 식으로 어쨌든 아무것도 검증 할 필요가 없습니다.

보다 일반적인 메모에서 관련 모델에 대한 유효성 검사를 ActiveRecord에 추가하는 것은 효과가 없습니다. 어떤 경우에는 거의 불가능합니다. 다른면에서는 제대로하기가 어렵습니다. 나는 그것이 잘못되었다는 것을 당신이 보았다고 생각합니다. 나는 그것을 피하고 당신이 (이 경우에는 Invoice#total을 가질 필요가 없도록) 당신의 데이터베이스를 디자인하려고 노력할 것을 제안한다.

2

당신의 예가 당신이 이전에 설명했던 것과 다르므로 정확히 당신이 검증하고 싶은 것이 명확하지 않습니다.

나는 사용해,이 같은 일을해야 생각 before_add callback : 나는 그것을 잘못 해석 될 수 있지만, totalinvoices 테이블의 열 경우, 나는 그것을 제거하는 것이 좋습니다

class Invoice < AR::Base 
    has_many :lines, :before_add => :validate_total 

    def validate_total(invoice, line) 
    totals = invoice.lines.sum(:line_value) 

    if totals + line.line_value > invoice.total 
     invoice.errors.add(:total, " should be lower or equal to the total amount of the invoice") 
     return false # I think you can alternatively raise an exception here 
    end 
    ... 
관련 문제