accepts_nested_attributes_for 하위 연결 유효성 검사 실패
Rails 모델 중 하나에서 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가 없기 때문에 유효성 검사가 실패합니다 (프로젝트가 저장되지 않았기 때문에).
Rails가 아래 패턴을 따르는 것 같습니다.
- 프로젝트 검증
- 작업 검증
- 프로젝트를 저장하다
- 작업 저장
패턴은 다음과 같아야합니다.
- 프로젝트 검증
- On Pass : 프로젝트를 저장하고 계속 ...
- 작업 검증
- On Pass : 작업 저장
- 실패시 : 프로젝트 삭제 (아마도 롤백 하시겠습니까?)
그래서 내 질문은 다음과 같이 요약됩니다. 부모 (프로젝트)가 저장되었지만 부모 (프로젝트) 모델을 저장하지 않은 후 Rails가 project_id = (또는 project =) 메서드와 자식 (작업)에 대한 유효성 검사를 실행하도록 할 수 있습니까? 자식 (작업)이 유효하지 않은 경우?
어떤 아이디어?
이 답변을 Rails 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
사용 :inverse_of
하고 validates_presence_of :parent
. 이렇게하면 유효성 검사 문제가 해결됩니다.
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
ID가 아닌 관계 만 확인합니다.
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project
end
As soon as the association is populated, ActiveRecord will consider the validation to have succeeded, whether or not the model is saved. You might want to investigate autosaving as well, to ensure the task's project is always saved:
class Task < ActiveRecord::Base
belongs_to :project, :autosave => true
validates_presence_of :project
end
Unfortunately none of the above suggestions work for me with Rails 2.3.5.
In my case, the project in a task is always nil if both are created using nested attributes. Only if I remove the validates_presence_of, the create goes through successfully. The unit test and the log show that all is created correctly.
So I'd now tend to add constraints to the DB instead of Rails as that seems to be more reliable in the first place.
You could just create the project and only add the projects if it passes validation:
tasks = params.delete(:task_attributes)
if Project.create(params)
Project.update_attributes(:task_attributes => tasks)
end
Ciao
Contrary to what bigo suggests, it's not always acceptable to save the parent object first and then the children. Usually you want to make sure all objects validate before you start saving them. That gives the user the chance to re-edit the input form and correct any errors.
The problem you describe will be fixed in Rails 3.0. I would have posted a link to the Lighthouse ticket, but stackoverflow.com does not allow this because I'm a new user (#fail). But for the time being, you can use the plugin "parental_control", which will fix your "bug".
'Program Tip' 카테고리의 다른 글
열거 형 클래스를 무순 맵 키로 사용할 수 없습니다. (0) | 2020.10.28 |
---|---|
Android 스튜디오 오류 : Error : CreateProcess error = 216,이 버전의 % 1은 실행중인 Windows 버전과 호환되지 않습니다. (0) | 2020.10.28 |
자바 단위 테스트, 디렉토리 레이아웃 (0) | 2020.10.28 |
모든 프로그래머가 알아야 할 .NET Framework 4의 사항 (0) | 2020.10.28 |
과학 컴퓨팅의 F # 성능 (0) | 2020.10.28 |