我正在尝试创建一个嵌套的子孙记录。孩子属于父母和孙子女。孩子不会 validates_presence_of 孙子,因为它还没有被保存。
我正在使用 Rails 2.3.11、Formtastic、InheritedResources 和 Haml,其他一切似乎都正常工作 - 例如,孙子的验证错误在父表单中正确填充,无效值被记住并呈现给用户. 除非一切都有效,否则父模型甚至不会尝试更新,就像它应该的那样。
我的代码是这样的,虽然在不同的问题域中:
class Project < ActiveRecord::Base
has_many :meetings, :dependent => :destroy
accepts_nested_attributes_for :meetings
end
class Meeting < ActiveRecord::Base
belongs_to :project
belongs_to :task
accepts_nested_attributes_for :task
validates_presence_of :task_id, :project_id
end
class Task < ActiveRecord::Base
has_many :meetings, :dependent => :destroy
end
项目总是已经存在,并且可能已经有我们不想看到的会议。任务可能通过其他会议属于其他项目,但在这种情况下,任务和会议总是新的。
在控制器中,我只在新操作上建立一个空白记录
@project.meetings.build
并像这样保存数据:
@project.update_attributes(params[:project])
并且在视图中
- semantic_form_for @project do |f|
- f.semantic_fields_for :meetings do |m|
- next unless m.object.new_record?
= m.semantic_errors :task_id
- m.object.build_task unless i.object.task
- m.semantic_fields_for :task do |t|
- f.inputs do
= t.input :task_field
= m.input :meeting_field
当我尝试保存表单时,我收到“任务不能为空白”的验证错误。好吧,当然,任务尚未保存,我正在尝试验证,但我没有它的 ID。
是否有一种简单而优雅的方法来确保在子记录之前构建孙记录(任务)?
我在会议模型中尝试过这样的事情:
before_validation_on_create do |meeting|
meeting.task.save if meeting.task.valid?
end
这似乎保存了任务,但会议仍然没有得到正确的 ID。同样的错误,但创建了任务记录。
我也试过这个:
before_validation_on_create do |meeting|
new_task = meeting.task.save if meeting.task.valid?
meeting.task = new_task
end
其中有引发 ActiveRecord::RecordNotFound "Couldn't find Task with ID=XX for Meeting with ID="的奇怪行为 - 我有点明白,但似乎是一条红鲱鱼。
我还尝试将:inverse_of 添加到所有关系并验证:task 而不是:task_id。奇怪的是,后者失败了,但似乎没有给出错误信息。
我在这里的实际目标是创建多个任务,每个任务都有一个关于先前选择的项目的初始会议......所以我可以对我的问题采取另一种方法 - 我可以在控制器中做一些简单而丑陋的事情,或者创建第一个在项目的 after_create 会议上。但这太漂亮了,太接近工作了。我在 :task_field 和 :meeting_field 上得到正确的验证错误这一事实表明我走在正确的轨道上。
我知道问题出在哪里,但不知道如何解决:我怀疑我遗漏了一些明显的东西。
谢谢!