为什么在创建具有重复值的记录时,`validates_uniqueness_of`没有验证失败?

时间:2013-07-04 03:51:24

标签: ruby-on-rails ruby-on-rails-3.2 rails-activerecord

我正在使用Ruby on Rails版本3.2.13。

这是我的模型定义:

module Recipes
  class Recipe < ActiveRecord::Base
    include ApplicationHelper

    attr_accessible :body, :title, :author, :photos, :tags

    has_many :photos
    has_many :favorites
    has_many :taggings
    has_many :tags, :through => :taggings

    belongs_to :author,
               :class_name => :User,
               :foreign_key => :author_id

    before_create :default_values
    before_save :create_slug

    validates_presence_of :title, :body, :author
    validates_uniqueness_of :title, :slug

    def create_slug
      self.slug = ApplicationHelper.slugify(self.title)
    end

    def default_values
      self.view_count ||= 0
    end
  end
end

如果我创建一个标题为“Test Title#1”的记录,并尝试创建另一个标题为“Test Title#1”的记录,则会收到一条验证错误,指出标题已经被删除。如果我创建一个标题为“Test Title#1”的记录,并尝试创建另一个标题为“Test Title 1”的记录,则会成功。两个记录生成的slug是相同的,'test-title-1',这不应该发生。

这是slugify的代码:

module ApplicationHelper
  def self.slugify(text)
    text.gsub(/[\W]+/, " ").strip.gsub(/[\s]+/, "-").downcase
  end
end

1 个答案:

答案 0 :(得分:2)

操作顺序(至少是您模型的相关操作)如下所示:

  1. before_validation回调。
  2. 验证
  3. before_save回调。
  4. 保存到数据库。
  5. 您可以在Active Record Callbacks Guide

    中找到完整列表

    因此,在执行验证后,您的create_slug方法(before_save回调)将被称为。如果你想确保你的slu is是独特的,你应该:

    before_validation :create_slug
    

    以便在验证执行之前设置slug。