module ActiveRecord::AttributeMethods::Serialization::ClassMethods
def serialize(attr_name, class_name_or_coder = Object, **options)
end
serialize :preferences, Rot13JSON
class User < ActiveRecord::Base
end
end
ActiveSupport::JSON.load(rot13(string))
def self.load(string)
# Deserializes a string from the database to an attribute value.
end
rot13(ActiveSupport::JSON.dump(value))
def self.dump(value)
# Serializes an attribute value to a string that will be stored in the database.
end
string.tr("a-zA-Z", "n-za-mN-ZA-M")
def self.rot13(string)
class Rot13JSON
===== Serialize the +preferences+ attribute using a custom coder
end
serialize :preferences, Hash
class User < ActiveRecord::Base
===== Serialize the +preferences+ +Hash+ using YAML
end
serialize :preferences, JSON
class User < ActiveRecord::Base
===== Serialize the +preferences+ attribute using JSON
end
serialize :preferences
class User < ActiveRecord::Base
===== Serialize the +preferences+ attribute using YAML
==== Examples
be used. Otherwise, the default will be +nil+.
this option is not passed, the previous default value (if any) will
* +:default+ - The default value to use when no value is provided. If
==== Options
+dump+ method may return +nil+ to serialize the value as +NULL+.
deserialized using the coder's load(string) method. The
using the coder's dump(value) method, and will be
* custom coder - The attribute value will be serialized
attribute value must respond to +to_json+.
* +JSON+ - The attribute value will be serialized as JSON. The
must be a +Hash+.
empty +Hash+ will be serialized as +NULL+. The attribute value
* +Hash+ - The attribute value will be serialized as YAML, but an
must be an +Array+.
empty +Array+ will be serialized as +NULL+. The attribute value
* +Array+ - The attribute value will be serialized as YAML, but an
The attribute value must respond to +to_yaml+.
* default - The attribute value will be serialized as YAML.
* +class_name_or_coder+ - Optional. May be one of the following:
* +attr_name+ - The name of the attribute to serialize.
==== Parameters
domain objects, consider using the ActiveRecord::Attributes API.
For more complex cases, such as conversion to or from your application
case.
objects transparently. There is no need to use #serialize in this
converted between JSON object/array syntax and Ruby +Hash+ or +Array+
for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be
Keep in mind that database adapters handle certain serialization tasks
custom coder class.
The serialization format may be YAML, JSON, or any custom format using a
will be handled automatically.
then specify the name of that attribute using this method and serialization
serialized object, and retrieved by deserializing into the same object,
If you have an attribute that needs to be saved to the database as a
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
def type_incompatible_with_serialize?(type, class_name)
def type_incompatible_with_serialize?(type, class_name) type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON || type.respond_to?(:type_cast_array, true) && class_name == ::Array end