문제

더 구체적으로 "모델에 최소한 X 유효한 관련 모델이 생성되어야한다는 것을 어떻게 검증합니까?". 나는 부모와 같은 형태로 만들어지는 중첩 모델을 검증하려고 노력했습니다 (궁극적으로 즉각적인 검증을 표시합니다). 인기있는 예로 다음 모델과 스키마를 가정 해 봅시다.

class Project
  include DataMapper::Resource

  property :id,     Serial
  property :title,  String, :nullable => false

  has 2..n, :tasks
end

class Task
  include DataMapper::Resource

  property :id,         Serial
  property :project_id, Integer,  :key => true
  property :title,      String,   :nullable => false

  belongs_to :project
end

모든 유효성 검사는 볼 수 있듯이 스키마 정의에서 수행됩니다. 여기서 중요한 것은 "has 2..n, :tasks".이 유효성 검사는 실제로 해시가 생성 할 Params의 중첩 작업 속성을 감안할 때 실제로 정상적으로 작동합니다. 유효한 작업. 그들이 생산한다면 유효하지 않은 그러나 작업은 작업이 생성되지 않으며 2 개의 작업 미만의 프로젝트로 끝날 것입니다. 유효하지 않은 프로젝트 객체.

내가 이해 한 바와 같이, 이것은 작업 속성이 작업을 저장하려고 시도 할 때까지 유효한 지 여부를 알 수 없기 때문입니다. 내가 아는 한 - 프로젝트 전에 작업을 저장할 수 없으며 작업이 유효 한 경우 프로젝트가 알지 못합니다. 이것을 가정 할 때 맞습니까?

어쨌든, 나는 빠른 답변이 있기를 바라고 있었지만, 나는 바랐던 것보다 훨씬 덜 사소한 것 같습니다. 제안이 전혀 없다면 대단히 감사하겠습니다.

도움이 되었습니까?

해결책

실제로 Datamapper에서 트랜잭션을 사용하여 좋은 솔루션을 찾았습니다. 기본적 으로이 거래는 부모 객체와 모든 자식 대상을 저장하려고 시도합니다. 하나가 저장되지 않으면 트랜잭션이 중지되고 아무것도 생성되지 않습니다. 모든 것이 잘되면 객체가 성공적으로 저장됩니다.

class Project
  def make
    transaction do |trans|
      trans.rollback unless save
      tasks.each do |task|
        unless task.save
          trans.rollback
          break
        end
      end
    end
  end
end

이것은 모든 것이 저장되기 전에 모든 것이 유효하다는 것을 보장합니다. 컨트롤러 코드에서 #Save 및 #UpDate 메소드를 변경해야했습니다.

다른 팁

데이터베이스 엔진이이를 지원하는 경우 지연된 제약 조건이 유용 할 수 있습니다.

그렇지 않으면, 저장된 절차를 작성하여 인서트를 수행 한 다음 저장된 절차의 공명이 올바른 검증 된 데이터 만 삽입되도록 할 수 있습니다.

모델 방법이 있습니다 valid? 이는 모델 객체가 저장되기 전에 유효성 검사를 실행합니다. 따라서 협회를 검증하는 간단한 방법은 사용하는 것입니다. validates_with_block' or 'validates_with_method 협회의 검증을 확인합니다.

이렇게 보일 것입니다

validates_with_block do
  if @tasks.all?{|t|t.valid?}
    true
  else
    [false, "you have an invalid task"]
  end
end

또는 당신은 볼 수 있습니다 DM- 연관성 검증기 또는 DM-Accepts-Nested-Attributes

편집하다: 추가 미친. 작업에 대한 유효성 검사를 실행 한 다음 유일한 오류가 협회와 관련된 오류인지 확인하십시오.

validates_with_block do
  if @tasks.all?{|t|t.valid?;!t.errors.any?{|e|e[0]==:project}}
    true
  else
    [false, "you have an invalid task"]
  end
end
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top