복붙노트

[RUBY-ON-RAILS] 아이 연결 검증 실패 accepts_nested_attributes_for

RUBY-ON-RAILS

아이 연결 검증 실패 accepts_nested_attributes_for

내 레일 모델 중 하나에 accepts_nested_attributes_for 사용하고, 나는 부모를 만든 후 아이들을 저장할.

형태는 완벽하게 작동하지만, 유효성 검사가 실패합니다. 단순화하기 위해 다음과 같은 상상 :

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

class Task < ActiveRecord::Base
  belongs_to :project

  validates_presence_of :project_id
  validates_associated :project
end

그리고 실행하고 있습니다 :

Project.create!(
  :name => 'Something',
  :task_attributes => [ { :name => '123' }, { :name => '456' } ]
)

프로젝트 모델을 저장하면 (프로젝트가 저장되지 않았기 때문에) 그들이 PROJECT_ID이 없기 때문에, 유효성 검사 작업에 실패합니다.

레일 아래의 패턴을 따르는 것 같습니다 :

패턴은해야합니다 :

내 질문에 귀결 그래서 : 부모 (프로젝트) AFTER 아이들 (작업)에 PROJECT_ID = (또는 프로젝트 =) 방법 및 검증을 실행하는 데 내가 얻을 수있는 방법 레일 아니라 부모 (프로젝트) 모델 저장, 저장된 자식 (작업) 유효하지 않은 경우?

어떤 아이디어?

해결법

  1. ==============================

    1.은 아래를 참조 그렇지 않으면, 레일 2에 대한이 답변을 사용 대답 inverse_of

    은 아래를 참조 그렇지 않으면, 레일 2에 대한이 답변을 사용 대답 inverse_of

    당신은 관련 프로젝트가 유효한 경우 PROJECT_ID를 확인하지 않음으로써이 문제를 해결할 수 있습니다.

    
    class Task < ActiveRecord::Base
      belongs_to :project
    
      validates_presence_of :project_id, :unless => lambda {|task| task.project.try(:valid?)}
      validates_associated :project
    end
    
  2. ==============================

    2.사용 : inverse_of 및 validates_presence_of : 부모입니다. 이 유효성 검사 문제를 해결해야한다.

    사용 : inverse_of 및 validates_presence_of : 부모입니다. 이 유효성 검사 문제를 해결해야한다.

       class Dungeon < ActiveRecord::Base
         has_many :traps, :inverse_of => :dungeon
       end
    
       class Trap < ActiveRecord::Base
         belongs_to :dungeon, :inverse_of => :traps
         validates_presence_of :dungeon
       end
    

    http://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_presence_of

    https://github.com/rails/rails/blob/73f2d37505025a446bb5314a090f412d0fceb8ca/activerecord/test/cases/nested_attributes_test.rb

  3. ==============================

    3.만 관계가 아닌 ID를 확인 :

    만 관계가 아닌 ID를 확인 :

    class Task < ActiveRecord::Base
      belongs_to :project
    
      validates_presence_of :project
    end
    

    즉시 협회가 채워집니다로, 액티브 모델이 저장되어 있는지 여부, 검증이 성공했다고 생각합니다. 당신은 작업의 프로젝트가 항상 저장하기 위해,뿐만 아니라 자동 저장 조사 할 수 있습니다 :

    class Task < ActiveRecord::Base
      belongs_to :project, :autosave => true
    
      validates_presence_of :project
    end
    
  4. ==============================

    4.위의 제안 불행하게도 아무도 레일 2.3.5와 나를 위해 작동하지 않습니다.

    위의 제안 불행하게도 아무도 레일 2.3.5와 나를 위해 작동하지 않습니다.

    모두가 중첩 된 속성을 사용하여 생성하는 경우 내 경우, 작업의 프로젝트는 항상 전무하다. 나는 validates_presence_of를 제거 만 있으면 성공적으로 거치는 만듭니다. 단위 테스트와 로그는 모두가 제대로 만들어 졌는지 보여줍니다.

    그 첫 번째 장소에서 더 안정적인 것 같다 나는 지금 대신 레일의 DB에 제약 조건을 추가하는 경향이 것 그래서.

  5. ==============================

    5.당신은 프로젝트를 생성하고 검증을 통과하는 경우에만 프로젝트를 추가 할 수 있습니다 :

    당신은 프로젝트를 생성하고 검증을 통과하는 경우에만 프로젝트를 추가 할 수 있습니다 :

    tasks = params.delete(:task_attributes)
    if Project.create(params)
      Project.update_attributes(:task_attributes => tasks)
    end
    

    안녕하세요.

  6. ==============================

    6.비고이 시사하는 것과는 달리, 먼저 다음 어린이 부모 개체를 저장하는 것이 허용되지이다. 일반적으로 당신은 당신이 그들을 저축을 시작하기 전에 모든 객체가 검증 만들고 싶어. 즉 재 편집에 사용자에게 입력 양식을 수있는 기회를 제공하고 오류를 수정.

    비고이 시사하는 것과는 달리, 먼저 다음 어린이 부모 개체를 저장하는 것이 허용되지이다. 일반적으로 당신은 당신이 그들을 저축을 시작하기 전에 모든 객체가 검증 만들고 싶어. 즉 재 편집에 사용자에게 입력 양식을 수있는 기회를 제공하고 오류를 수정.

    당신이 설명하는 문제는 레일 3.0에서 해결 될 것입니다. 나는 등대 티켓에 대한 링크를 게시 한 것이지만, stackoverflow.com을 나는 새 사용자 (#fail를)이기 때문에이를 허용하지 않습니다. 그러나 당분간, 당신은 당신의 "버그"가 해결됩니다 플러그인 "parental_control"를 사용할 수 있습니다.

  7. from https://stackoverflow.com/questions/935650/accepts-nested-attributes-for-child-association-validation-failing by cc-by-sa and MIT license