如何执行“before_serialize”代码?或者如何在序列化属性之前对其进行清理?

问题描述 投票:0回答:1

我遵循此模式以确保我的所有属性在保存之前都已标准化:

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
之前执行的。

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

ruby-on-rails serialization callback
1个回答
0
投票

为了确保所有属性在保存之前都已标准化 - 覆盖设置器:

class MyModel < ApplicationRecord
  # @value [String]
  # @return [String]
  def name=(value)
    super(value.strip)
  end
  
  # @value [String]
  # @return [String]
  def email=(value)
    super(value.strip)
  end
  
  # @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

© www.soinside.com 2019 - 2024. All rights reserved.