在已销毁的嵌套模型轨中的validates_uniqueness_of

aru*_*run 18 ruby-on-rails nested-forms validates-uniqueness-of

我有一个Project模型,它接受Task的嵌套属性.

class Project < ActiveRecord::Base  
  has_many :tasks

  accepts_nested_attributes_for :tasks, :allow_destroy => :true

end

class Task < ActiveRecord::Base  
validates_uniqueness_of :name end
Run Code Online (Sandbox Code Playgroud)

任务模型中的唯一性验证在更新Project时会出现问题.

在编辑项目时,我删除任务T1,然后添加一个同名T1的新任务,唯一性验证限制了项目的保存.

params hash看起来像

task_attributes => { {"id" =>
"1","name" => "T1", "_destroy" =>
"1"},{"name" => "T1"}}
Run Code Online (Sandbox Code Playgroud)

在销毁旧任务之前完成对任务的验证.因此验证失败.任何想法如何验证,它不会考虑任务被销毁?

Rai*_*ing 16

Andrew France在这个线程中创建了一个补丁,验证在内存中完成.

class Author
  has_many :books

  # Could easily be made a validation-style class method of course
  validate :validate_unique_books

  def validate_unique_books
    validate_uniqueness_of_in_memory(
      books, [:title, :isbn], 'Duplicate book.')
  end
end

module ActiveRecord
  class Base
    # Validate that the the objects in +collection+ are unique
    # when compared against all their non-blank +attrs+. If not
    # add +message+ to the base errors.
    def validate_uniqueness_of_in_memory(collection, attrs, message)
      hashes = collection.inject({}) do |hash, record|
        key = attrs.map {|a| record.send(a).to_s }.join
        if key.blank? || record.marked_for_destruction?
          key = record.object_id
        end
        hash[key] = record unless hash[key]
        hash
      end
      if collection.length > hashes.length
        self.errors.add_to_base(message)
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

  • add_to_base已被弃用,在3.1中不可用.使用self.errors.add(:base,message) (3认同)