在Rails 4中序列化和before_save

时间:2021-08-15 23:28:07

I have a DocumentType model w/ a extensions attribute. In my form I'm allowing people to insert those extensions into the form.

我有一个DocumentType model w/ a extensions属性。在我的表单中,我允许人们将这些扩展插入到表单中。

I want to be able to parse that input before saving, stripping out any invalid options, convert it into an array and have Rails serialize it.

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

I have the following code but I just end up w/ the input that the user gave in the form instead of an array:

我有下面的代码,但我只是结束了用户在表单中给出的输入,而不是数组:

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 个解决方案

#1


10  

The key to understanding what's happening is knowing when serialization occurs. By inspecting serialization.rb in activerecord you'll see that the serialization magic happens by overriding type_cast_attribute_for_write, which is called on write_attribute. That is, on attribute assignment. So when you do:

理解正在发生的事情的关键是知道何时发生序列化。通过检查序列化。在activerecord中,您将看到序列化魔术是通过重写type_cast_attribute_for_write(在write_attribute上调用)实现的。也就是属性赋值。所以,当你做的事:

document_type.extensions = something

something gets serialized and written to the extensions attribute. That is way before the save takes place. In fact, you don't even have to call save on document_type to have the attribute serialized.

一些东西被序列化并写入到扩展属性。这是在保存发生之前的方法。实际上,您甚至不需要调用document_type上的save来序列化属性。

The best workaround I know is to override extensions= on DocumentType. Something like:

我所知道的最好的解决方法是重写DocumentType的extensions=。喜欢的东西:

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

#2


-1  

I believe this append because the value of extensions is serialized while the model is validated by Rails, and your process_extensions method is called later (before the model is saved) and does not act as expected

我相信这个append,因为扩展的值是序列化的,而模型是通过Rails进行验证的,并且您的process_extensions方法稍后(在模型保存之前)调用,并且不像预期的那样运行。

Try to use before_validate instead

尝试使用before_validate代替

before_validate :process_extensions

before_validate:process_extensions

#1


10  

The key to understanding what's happening is knowing when serialization occurs. By inspecting serialization.rb in activerecord you'll see that the serialization magic happens by overriding type_cast_attribute_for_write, which is called on write_attribute. That is, on attribute assignment. So when you do:

理解正在发生的事情的关键是知道何时发生序列化。通过检查序列化。在activerecord中,您将看到序列化魔术是通过重写type_cast_attribute_for_write(在write_attribute上调用)实现的。也就是属性赋值。所以,当你做的事:

document_type.extensions = something

something gets serialized and written to the extensions attribute. That is way before the save takes place. In fact, you don't even have to call save on document_type to have the attribute serialized.

一些东西被序列化并写入到扩展属性。这是在保存发生之前的方法。实际上,您甚至不需要调用document_type上的save来序列化属性。

The best workaround I know is to override extensions= on DocumentType. Something like:

我所知道的最好的解决方法是重写DocumentType的extensions=。喜欢的东西:

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

#2


-1  

I believe this append because the value of extensions is serialized while the model is validated by Rails, and your process_extensions method is called later (before the model is saved) and does not act as expected

我相信这个append,因为扩展的值是序列化的,而模型是通过Rails进行验证的,并且您的process_extensions方法稍后(在模型保存之前)调用,并且不像预期的那样运行。

Try to use before_validate instead

尝试使用before_validate代替

before_validate :process_extensions

before_validate:process_extensions

相关文章