序列化&在Rails 4中的before_save

时间:2013-07-17 14:14:24

标签: ruby-on-rails ruby activerecord

我有DocumentType模型w / 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

2 个答案:

答案 0 :(得分:10)

了解正在发生的事情的关键是在序列化发生时了解 。通过检查activerecord中的serialization.rb,您将看到序列化魔法通过覆盖在write_attribute上调用的type_cast_attribute_for_write而发生。也就是说,属性分配。所以当你这样做时:

document_type.extensions = something

某些内容被序列化并写入extensions属性。这是保存发生之前的方式。实际上,您甚至不必调用document_type上的save来将属性序列化。

我知道的最佳解决方法是覆盖DocumentType上的extensions=。类似的东西:

def extensions=(value)
  value = [*value.gsub(/[^a-z ]+/i, '').split(' ')].uniq
  write_attribute :extensions, value
end

答案 1 :(得分:-1)

我认为这是追加的,因为extensions的值在Rails验证模型时被序列化,并且稍后调用process_extensions方法(在模型保存之前)并且没有按预期运行

尝试使用before_validate而不是

before_validate :process_extensions