我在具有关联的模型中有一个相当复杂的业务逻辑。我想允许用户保存不完整(无效)模型以备将来完成。因此,在我的控制器中,我打电话给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>
答案 0 :(得分:2)
运行save(validate: false)
不会使回调关闭,您必须在保存后运行一些其他代码才能使记录通过验证。
检查您的before/after_save
回调,并发布模型。
编辑:
对新记录使用嵌套属性会给您带来验证问题,它最适合现有记录,因为新记录上的关联不正确。在this answer的最后一段中有一个很好的解释和解决方法。