为什么validates_associated保存父母与无效的孩子?

时间:2015-11-04 20:19:44

标签: ruby-on-rails

此rails应用程序在使用非crud操作时会保存无效的父/子,但在使用正常的crud操作时会引发相应的错误。

class Job < ActiveRecord::Base
  has_many :locations
  accepts_nested_attributes_for :locations
  validates_presence_of :locations
  validates_associated :locations
end

...

class Location < ActiveRecord::Base
  belongs_to :job
  validates_presence_of :job
  has_many :line_items
  accepts_nested_attributes_for_line_items
  validates_presence_of :line_items
  validate :comments_if_any_line_items_skipped
private
  def comments_if_any_line_items_skipped
    if line_items.present? and line_items.where(skipped: true).present?
      errors.add(:reason, 'cannot be blank if any line items are skipped?') if comments.blank?
    end
  end
end

...

class JobsController < ApplicationController
  def create
    @job = Job.new(job_params.merge(started: Time.now))
    if @job.save
      redirect_to perform_job_url(@job)
    end
  end
  def stop
    @job = Job.find(params[:id])
    if @job.update(job_params.merge(stopped: Time.now))
      redirect_to @job
    end
  end
end

使用预先填充的位置和订单项创建作业,并自动保存开始时间,但位置的注释为空白,并且跳过的订单项默认为false。在作业的执行页面上,可以记录可以记录注释的表单,并且可以将行项目标记为已跳过。保存表单后,将记录作业的停止时间以及关联的位置和行项目属性。

无论出于何种原因,无论我如何编写代码,如果位置处于无效状态,作业将更新停止时间(跳过行项目时不进行评论)。

在我看来,作业模型中的validates_associated :locations行应该阻止这种情况。

需要注意的另一点:作业控制器具有完全正常的编辑/更新操作,如果关联的位置处于无效状态,则无法保存作业。

0 个答案:

没有答案