保存后恢复Rails回调(验证:false)

时间:2017-08-01 10:10:53

标签: ruby-on-rails

我在具有关联的模型中有一个相当复杂的业务逻辑。我想允许用户保存不完整(无效)模型以备将来完成。因此,在我的控制器中,我打电话给instance.save(validate: false)

以下是我从应用程序中提取的3个模型。 这些模型可能过于夸张,因为我只提取了相关部分。

1)Container型号:

class Container < ApplicationRecord
    Languages = %w(fr en de it es)

    belongs_to :name, class_name: "Name", foreign_key: :name_id

    accepts_nested_attributes_for :name

    validates :name, presence: true

    # create an empty model 
    def self.create_new
        c = Container.new

        c.name = Name.new
        c.name.save
        Languages.each do |l|
            c.name.translations << NameItem.new(language: l, text: "")
        end # Languages.each do |l|

        c.description = Description.new
        c.description.save
        Languages.each do |l|
            c.description.translations << DescriptionItem.new(language: l, text: "")
        end # Languages.each do |l|

        c
    end 
end

2)Name型号:

class Name < ApplicationRecord
    has_many :translations, class_name: "NameItem", foreign_key: :parent_id

    accepts_nested_attributes_for :translations
end

3)NameItem模型:

class NameItem < ApplicationRecord
    validates :language, presence: true
    validate  :text_validation

    private
    def text_validation
        return if language.nil?

        errors.add(:text, :blank_text, language: language) if text.nil? || text.size == 0
    end
end

鉴于以下指令序列,我不知道为什么最后一条指令(instance.valid?)返回true。在我看来,验证回调被禁用,但我不确定这是否是正确的诊断。这可能与使用accepts_nested_attributes_for?:

有关
# create an invalid model (since empty)
instance = Container.create_new

# check that this instance is invalid
instance.valid? # returns false, this is the expected behavior

# save the model, skipping the validations
instance.save(validate: false)

# now instance.valid? will always return true, because it will
# skip the validations. How can I restore the callbacks ?
instance.valid? # returns true, but this is not the desired behavior,
                # hence my question

我尝试使用以下说明禁用并重新启用回调,但无济于事。

[:create, :save, :update].each do |action|
  Container.skip_callback(action)
end

[:create, :save, :update].each do |action|
  Container.set_callback(action)
end

所以我的问题是:在调用instance.save(validate: false)后,我需要运行哪些指令才能使instance.valid?确实再次执行验证检查并返回false?< / p>

1 个答案:

答案 0 :(得分:2)

运行save(validate: false)不会使回调关闭,您必须在保存后运行一些其他代码才能使记录通过验证。

检查您的before/after_save回调,并发布模型。

编辑:

对新记录使用嵌套属性会给您带来验证问题,它最适合现有记录,因为新记录上的关联不正确。在this answer的最后一段中有一个很好的解释和解决方法。