2

我有一个DocumentType带有extensions属性的模型。在我的表单中,我允许人们将这些扩展插入到表单中。

我希望能够在保存之前解析该输入,去除任何无效选项,将其转换为数组并让 Rails 对其进行序列化。

我有以下代码,但我最终得到的是用户以表单而不是数组提供的输入:

class DocumentType < ActiveRecord::Base
  serialize :extensions

  before_save :process_extensions

  def process_extensions
    self.extensions = [*self.extensions.gsub(/[^a-z ]+/i, '').split(' ')].uniq
  end
end
4

2 回答 2

11

了解正在发生的事情的关键是知道序列化何时发生。通过检查activerecord 中的serialization.rb,您会发现序列化魔法是通过覆盖 type_cast_attribute_for_write 来实现的,它在 write_attribute 上调用。也就是在属性赋值上。所以当你这样做时:

document_type.extensions = something

某些东西被序列化并写入扩展属性。那是在保存发生之前。事实上,您甚至不必在 document_type 上调用 save 来序列化属性。

我知道的最好的解决方法是覆盖extensions=DocumentType。就像是:

def extensions=(value)
  value = [*value.gsub(/[^a-z ]+/i, '').split(' ')].uniq
  write_attribute :extensions, value
end
于 2013-07-23T20:00:04.150 回答
-1

我相信这个附加,因为在extensionsRails 验证模型时,值是序列化的,并且process_extensions稍后调用您的方法(在保存模型之前)并且没有按预期运行

尝试改用 before_validate

before_validate :process_extensions

于 2013-07-23T19:25:30.307 回答