假设我有一个类如下:
class Book < ActiveRecord::Base
validates :title, :length => {:maximum => 10}
end
有没有办法(安装宝石?)我可以让ActiveRecord根据最大长度自动截断值?
例如,当我写:
b = Book.new
b.title = "123456789012345" # this is longer than maximum length of title 10
b.save
应保存并返回true?
如果没有这种方式,你会如何建议我更普遍地面对这样的问题?
答案 0 :(得分:5)
好吧,如果你想要将值截断,如果它太长,你就不需要验证,因为它总是会通过。我会这样处理:
class Book < ActiveRecord::Base
before_save :truncate_values
def truncate_values
self.title = self.title[0..9] if self.title.length > 10
end
end
答案 1 :(得分:2)
我想出了一个截断的新验证器。我是这样做的:
我在“app”文件夹中创建了“validators”文件夹,然后使用以下内容创建了文件“length_truncate_validator.rb”:
class LengthTruncateValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
ml = options[:maximum]
record.send("#{attribute}=", value.mb_chars.slice(0,ml)) if value.mb_chars.length > ml unless value.nil? or ml.nil?
end
class << self
def maximum(record_class, attribute)
ltv = record_class.validators_on(attribute).detect { |v| v.is_a?(LengthTruncateValidator) }
ltv.options[:maximum] unless ltv.nil?
end
end
end
在我的模型课中,我有类似的东西:
class Book < ActiveRecord::Base
validates :title, :length_truncate => {:maximum => 10}
end
非常方便,按我要求的方式工作。
但是,如果你认为这个可以改进或以其他方式完成,那么欢迎你。
答案 2 :(得分:1)
我喜欢使用before_validation回调的想法。这是我的刺刀,它会自动将所有字符串都截断到数据库的限制范围内
before_validation :truncate_strings
def truncate_strings
self.class.columns.each do |column|
next if column.type != :string
if self[column.name].length > column.limit
self[column.name] = self[column.name][0...column.limit]
end
end
end
答案 3 :(得分:0)
这在2011年可能不是一个选项,但现在可以使用before_validation
回调。
class Book < ApplicationRecord
before_validation do
if self.params && self.params.length > 1000
self.params = self.title[0...10]
end
end
validate :title, length: { maximum: 10 }, allow_nil: true
end