我有一个简单的大小写方法,这样当用户在乐队页面中提交一个新乐队时,它会返回第一个大写字母。
在我的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
。如果我再次输入someband
,ActiveRecord
会将其视为唯一身份,而我会获得另一个Someband
。唯一可行的方法是输入Someband
。我该如何解决这种情况?
答案 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