我遵循这个模式,以确保我的所有属性在保存之前都是规范化的:

class MyModel < ApplicationRecord
  before_validation :normalize_attributes

  def normalize_attributes
    self.name&.strip!
    self.email&.strip!
  end
end

我还有一些更复杂的:

def normalize_attributes
  # Transform to array if it is a string with things
  # separated by comas
  if self.favorite_things.is_a? String
    self.favorite_things = self.favorite_things.split(",").map(&:strip)
  end
end

它可以工作,但问题是当我把这个属性添加到serialized个属性中时,它失败了:

serialize :favorite_things, Array

就像这里:

my_model.update(favorite_things: "ONE, TWO, THREE")

错误:

Error:
ActiveRecord::SerializationTypeMismatch: can't serialize `favorite_things`: was supposed to be a Array, but was a String. -- "ONE, TWO, THREE"

serialize命令在before_validation之前执行.

如何在序列化属性之前对属性进行清理?

推荐答案

为了确保在保存之前所有的属性都被规范化了—覆盖设置器:

class MyModel < ApplicationRecord
  # @param value [String]
  # @return [String]
  def name=(value)
    super(value.strip)
  end
  
  # @param value [String]
  # @return [String]
  def email=(value)
    super(value.strip)
  end
  
  # @param value [String, Array]
  # @return [Array]
  def favorite_things=(value)
    return super(value) unless value.is_a? String
    
    super(favorite_things.split(",").map(&:strip))
  end
end

https://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors

Ruby-on-rails相关问答推荐

如何判断是否定义了Rails模型?

Rails 7中的Turbo流

如何将 ActionController::RoutingError 分类为 Sentry 中的错误

NameError:未定义的局部变量或方法记录器

如何在 Windows 中更新 ruby

在允许用户使用设计(rails)登录之前判断用户是否处于活动状态

如何在 rails 中指定和验证枚举?

更改 form_for rails 3.1 生成的 html 表单 ID

如何在where子句中组合两个条件?

rails 4.0, rake db:sessions:create

单击表格行(使用 bootstrap 程序)时,如何使用模式显示数据?

如何在 routes.rb 中使用 301 或 302 进行重定向

Rails如何对列求和?

Rails Rake 任务 - 访问模型类

Post.all.map(&:id) 是什么意思?

如何在 Rails 迁移中添加一些插入?

在rails国际化yml文件中传递变量

Postgresql JSON 数据列不同

如何从 ApplicationHelper 调用 ApplicationController 方法

为什么 Mac OS X 带有 ruby​​/rails?