开发者

Rails: Why does failing validate_uniqeness still allow save?

开发者 https://www.devze.com 2023-02-14 13:53 出处:网络
-- Question rewritten based on further testing -- So, my app has_many Folders which belong_to Collections.

-- Question rewritten based on further testing --

So, my app has_many Folders which belong_to Collections. Folders are nested, they can also belong_to another Folder.

I want to validate uniqueness of the folder names within each collection. When I create folders at the top level this works, but when I create it in lower levels it does not work. Here are the models:

class Folder < ActiveRecord::Base
  # CALLBACKS
  before_create :associate_collection

  # RELATIONSHIPS
  belongs_to :collection
  belongs_to :parent, :class_name => 'Folder'
  has_many :subfolders, :开发者_Python百科class_name => 'Folder', :foreign_key => :parent_id

  # VALIDATIONS
  validates_presence_of :name
  validates_uniqueness_of :name, :scope => :collection_id

  private

  def associate_collection
    if self.collection.nil?
    self.collection = self.parent.collection
    end
  end
end

class Collection < ActiveRecord::Base

  # RELATIONSHIPS
  has_one :root_folder, :class_name => 'Folder', :conditions => { :parent_id => nil }
  has_many :folders

  # CALLBACKS
  after_create :setup_root_folder

  private

  def setup_root_folder
    self.create_root_folder(:name=>'Collection Root')
    self.save!
  end

end

Here's an abridged example of what happens in the console:

c = Collection.new(:name=>'ExampleCollection')
#<Collection id: 1>

root = c.root_folder
#<Folder id: 1, collection_id: 1>

f1 = root.subfolders.create(:name=>'Test')
#<Folder id: 2 collection_id: 1> 

f1.valid?
# TRUE

f2 = root.subfolders.create(:name=>'Test')
#<Folder id: 3 collection_id: 1>

f2.valid?
# FALSE

f1.valid?
# FALSE

So, while the collection is being associated with a subfolder correctly, its not triggering the validations correctly until after it's saved.

Suggestions?


The only way I can think to explain it is that the validation is being called before the collection_id is assigned, due to the syntax you are using. Maybe try

Folder.create(:collection => @collection, :name => 'example')

and see if it changes anything.


Doh.

My associate_collection callback needs to happen before_validation, not before_create.

Fixed. Thanks for looking guys!

0

精彩评论

暂无评论...
验证码 换一张
取 消