ActiveRecord,validates_uniqueness_of:如果我有一个大写方法,名称不会捕获非单一性

时间:2015-08-28 23:05:48

标签: ruby-on-rails ruby activerecord

我有一个简单的大小写方法,这样当用户在乐队页面中提交一个新乐队时,它会返回第一个大写字母。 在我的Band课程中,我还有一个validates_uniqueness_of :band_name,以查看是否已有band具有相同的条目。请参阅以下代码:

  class Band < ActiveRecord::Base
    has_and_belongs_to_many :venues
    validates :band_name, :presence => true
    before_save :title_case
    validates_uniqueness_of :band_name

  private

    def title_case
      self.band_name.capitalize!
    end

  end

因此,如果我输入someband,则会创建它并将其显示为Someband。如果我再次输入somebandActiveRecord会将其视为唯一身份,而我会获得另一个Someband。唯一可行的方法是输入Someband。我该如何解决这种情况?

3 个答案:

答案 0 :(得分:5)

我认为你想要做的就是这个

validates_uniqueness_of :band_name, :case_sensitive :false, allow_blank: false

查看http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html

  

:case_sensitive - 查找完全匹配。被非文字忽略   列(默认为true)。

答案 1 :(得分:1)

您的代码无效的原因是因为验证发生在before_save回调被触发之前。查看ActiveRecord::Callbacks列表,了解调用内容的顺序。

MZaragoza's answer是一个很好的选项,可以让您的验证工作无论用户输入的内容如何。它会阻止添加“someband”和“SomeBand”之类的内容。我建议将其作为解决方案的一部分。

与您已有的代码非常相似的另一个选项是切换到使用before_validation回调:

before_validation :title_case

我强烈建议每当与您的验证规则相关的数据发生更改时使用before_validation回调而不是before_save回调,无论您做出哪些其他更改。这可确保您检查计划保存到数据库的模型的实际状态。

答案 2 :(得分:0)

您可以使用属性设置器而不是before_save回调来大写您的值,而不会推迟。

def band_name=(value)
  self['band_name'] = value && value.mb_chars.capitalize
end