如何使Rails ActiveRecord自动截断设置为具有最大长度的属性的值?

p.m*_*los 8 activerecord attributes ruby-on-rails max

假设我有一个类,如下所示:

class Book < ActiveRecord::Base

  validates :title, :length => {:maximum => 10}

end
Run Code Online (Sandbox Code Playgroud)

有没有办法(安装宝石?)我可以让ActiveRecord根据最大长度自动截断值?

例如,当我写:

b = Book.new
b.title = "123456789012345" # this is longer than maximum length of title 10
b.save
Run Code Online (Sandbox Code Playgroud)

应该保存并返回true吗?

如果没有这种方式,你会如何建议我更普遍地面对这样的问题?

kar*_*kie 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
Run Code Online (Sandbox Code Playgroud)


p.m*_*los 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
Run Code Online (Sandbox Code Playgroud)

在我的模型类中,我有类似的内容:

class Book < ActiveRecord::Base

  validates :title, :length_truncate => {:maximum => 10}

end
Run Code Online (Sandbox Code Playgroud)

这非常方便并且按照我需要的方式工作。

但是,如果您认为可以改进或以其他方式完成此操作,我们欢迎您。