Spec-Zone.ru › Ruby on Rails 7.0

модуль ActiveRecord::AttributeMethods::Serialization::ClassMethods

Публичные методы экземпляров

serialize(attr_name, class_name_or_coder = Object, **options) Показать исходный код
# File activerecord/lib/active_record/attribute_methods/serialization.rb, line 119
def serialize(attr_name, class_name_or_coder = Object, **options)
  # When ::JSON is used, force it to go through the Active Support JSON encoder
  # to ensure special objects (e.g. Active Record models) are dumped correctly
  # using the #as_json hook.
  coder = if class_name_or_coder == ::JSON
    Coders::JSON
  elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
    class_name_or_coder
  else
    Coders::YAMLColumn.new(attr_name, class_name_or_coder)
  end

  attribute(attr_name, **options) do |cast_type|
    if type_incompatible_with_serialize?(cast_type, class_name_or_coder)
      raise ColumnNotSerializableError.new(attr_name, cast_type)
    end

    cast_type = cast_type.subtype if Type::Serialized === cast_type
    Type::Serialized.new(cast_type, coder)
  end
end

Если у вас есть атрибут, который необходимо сохранить в базе данных как сериализованный объект, а затем извлечь, десериализовав в тот же объект, то укажите имя этого атрибута с помощью этого метода, и сериализация будет обрабатываться автоматически.

Формат сериализации может быть YAML, JSON или любой другой пользовательский формат, использующий пользовательский класс кодера.

форматы

serialize attr_name [, class_name_or_coder]

                     |                           |  database storage   |
class_name_or_coder  | attribute read/write type | serialized | NULL   |
---------------------+---------------------------+------------+--------+
  <not given>        | any value that supports   |    YAML    |        |
                     |   .to_yaml                |            |        |
                     |                           |            |        |
Array                | Array **                  |    YAML    |  []    |
                     |                           |            |        |
Hash                 | Hash **                   |    YAML    |  {}    |
                     |                           |            |        |
JSON                 | any value that supports   |    JSON    |        |
                     |   .to_json                |            |        |
                     |                           |            |        |
<custom coder class> | any value supported by    |   custom   | custom |
                     | the custom coder class    |            |        |

** Если class_name_or_coder является Array или Hash, извлечённые значения всегда будут иметь тот же тип, а присвоение любого значения должно быть этого типа или будет вызвано SerializationTypeMismatch.

Пользовательские кодеры

Можно указать пользовательский класс или модуль кодера. Он должен иметь self.load и self.dump методы класса/модуля. self.dump(object) будет вызван для сериализации объекта и должен вернуть сериализованное значение для хранения в базе данных (nil для хранения в виде NULL). self.load(string) будет вызван для обратного процесса и загрузки (десериализации) из базы данных.

Помните, что адаптеры баз данных обрабатывают некоторые задачи сериализации за вас. Например: типы json и jsonb в PostgreSQL будут преобразовываться между синтаксисом JSON-объекта/массива и Ruby Hash или Array объектами прозрачно. В этом случае нет необходимости использовать serialize.

Для более сложных случаев, таких как преобразование в или из объектов вашей предметной области, рассмотрите использование API ActiveRecord::Attributes.

Параметры

  • attr_name - Имя поля, которое должно быть сериализовано.

  • class_name_or_coder - Необязательно, может быть Array или Hash или JSON или пользовательским классом или модулем кодера, который отвечает на .load и .dump. См. таблицу выше.

Опции

default Значение по умолчанию для использования, когда значение не указано. Если эта опция не передана, будет использовано предыдущее значение по умолчанию (если таковое есть). В противном случае значением по умолчанию будет nil.

Пример

# Serialize a preferences attribute using YAML coder.
class User < ActiveRecord::Base
  serialize :preferences
end

# Serialize preferences using JSON as coder.
class User < ActiveRecord::Base
  serialize :preferences, JSON
end

# Serialize preferences as Hash using YAML coder.
class User < ActiveRecord::Base
  serialize :preferences, Hash
end

# Serialize preferences using a custom coder.
class Rot13JSON
  def self.rot13(string)
    string.tr("a-zA-Z", "n-za-mN-ZA-M")
  end

  # returns serialized string that will be stored in the database
  def self.dump(object)
    ActiveSupport::JSON.encode(object).rot13
  end

  # reverses the above, turning the serialized string from the database
  # back into its original value
  def self.load(string)
    ActiveSupport::JSON.decode(string.rot13)
  end
end

class User < ActiveRecord::Base
  serialize :preferences, Rot13JSON
end

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API