【问题标题】:Rails 3.0 Skip validations for nested attributesRails 3.0 跳过嵌套属性的验证
【发布时间】:2012-05-30 19:15:35
【问题描述】:

我需要能够在不对其自身或其嵌套属性运行验证的情况下保存记录。我卡在 Rails 3.0 中,无法更新到新版本。

我有一份报告,每份报告都有很多回复(问题的答案)。响应嵌套在报告表单中。

用户应该能够以两种方式保存报告:提交以供审核,运行所有验证,以及稍后保存并完成,其中不对报告或嵌套响应运行验证。这需要对创建和更新操作都有效。

我目前正在尝试使用条件验证。这适用于更新但不适用于创建。问题是这一行:

validate :has_answer_if_required, :if => Proc.new { |response| !response.report.finish_later? }

报告尚不存在,因此活动记录找不到此回复的报告。这就是它崩溃的地方。

对于这个问题有很多建议的解决方案,但我无法让它们在 Rails 3.0 中工作。例如,update_attributes(attributes, :validate => false) 在 Rails 3.0 中不可用。

那么,如何跳过嵌套属性中的验证?

class Report < ActiveRecord::Base
  has_many :responses, :order => "created_at asc", :autosave => true
  accepts_nested_attributes_for :responses
  ...
end

class Response < ActiveRecord::Base
  belongs_to :report
  validates_associated  :report

  validate :has_answer_if_required, :if => Proc.new { |response| !response.report.finish_later? }
  validate :correct_answer_or_comment, :if => Proc.new { |response| !response.report.finish_later? }
end

class ReportsController < BaseController

  def update
    @report = Report.find(params[:id])
    @report.attributes = params[:report]

    if params[:finish_later].nil?
      @report.update_attribute(:finish_later, false)
      if @report.save!
      redirect_to :action => :index
    else
      render :template => "reports/edit"
    end
    else
      @report.finish_later = true
      @report.save(:validate => false)
      redirect_to :action => :index
    end
  end

  def create
    @report = Report.new(params[:report])
    if params[:finish_later].nil?
      @report.finish_later = false
      if @report.save!
        redirect_to :action => :index
      else
        render :template => "reports/edit"
      end
    else
      @report.finish_later = true
      @report.save!(:validate => false)
      redirect_to :action => :index
    end
  end
end

【问题讨论】:

标签: ruby-on-rails-3 validation nested-attributes


【解决方案1】:

不确定它是否适用于嵌套属性,虽然我认为它应该......但试试 ValidationSkipper:

https://github.com/npearson72/validation_skipper

只需确保在要跳过的对象上调用skip_validation_for。由于嵌套属性将行为传递给它们的子对象,因此您可以直接在父对象上调用此方法。试试看吧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多