From 29b2a571ad928f4d153754c7d357b788935cb18f Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Thu, 17 Feb 2022 14:47:56 -0600 Subject: [PATCH] Improve serialize API doc [ci-skip] The "Serialization formats" ASCII table confused the syntax highlighter. Additionally, the "database storage" column headers were a bit muddled, and the "NULL" column was difficult to decipher. This commit relocates that information to the `class_name_or_coder` parameter description, expressed as a list of accepted values. This commit also fixes the custom coder code example (which called `string.rot13` instead of `rot13(string)`), and improves the documentation formatting in various spots. --- .../attribute_methods/serialization.rb | 84 ++++++++----------- 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index c7c61128ea253..8361f3ac3f5b3 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -24,38 +24,6 @@ module ClassMethods # The serialization format may be YAML, JSON, or any custom format using a # custom coder class. # - # === Serialization formats - # - # serialize attr_name [, class_name_or_coder] - # - # | | database storage | - # class_name_or_coder | attribute read/write type | serialized | NULL | - # ---------------------+---------------------------+------------+--------+ - # | any value that supports | YAML | | - # | .to_yaml | | | - # | | | | - # Array | Array ** | YAML | [] | - # | | | | - # Hash | Hash ** | YAML | {} | - # | | | | - # JSON | any value that supports | JSON | | - # | .to_json | | | - # | | | | - # | any value supported by | custom | custom | - # | the custom coder class | | | - # - # ** If +class_name_or_coder+ is +Array+ or +Hash+, values retrieved will - # always be of that type, and any value assigned must be of that type or - # +SerializationTypeMismatch+ will be raised. - # - # ==== Custom coders - # A custom coder class or module may be given. This must have +self.load+ - # and +self.dump+ class/module methods. self.dump(object) will be called - # to serialize an object and should return the serialized value to be - # stored in the database (+nil+ to store as +NULL+). self.load(string) - # will be called to reverse the process and load (unserialize) from the - # database. - # # Keep in mind that database adapters handle certain serialization tasks # for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be # converted between JSON object/array syntax and Ruby +Hash+ or +Array+ @@ -67,55 +35,71 @@ module ClassMethods # # ==== Parameters # - # * +attr_name+ - The field name that should be serialized. - # * +class_name_or_coder+ - Optional, may be be +Array+ or +Hash+ or - # +JSON+ or a custom coder class or module which responds to +.load+ - # and +.dump+. See table above. + # * +attr_name+ - The name of the attribute to serialize. + # * +class_name_or_coder+ - Optional. May be one of the following: + # * default - The attribute value will be serialized as YAML. + # The attribute value must respond to +to_yaml+. + # * +Array+ - The attribute value will be serialized as YAML, but an + # empty +Array+ will be serialized as +NULL+. The attribute value + # must be an +Array+. + # * +Hash+ - The attribute value will be serialized as YAML, but an + # empty +Hash+ will be serialized as +NULL+. The attribute value + # must be a +Hash+. + # * +JSON+ - The attribute value will be serialized as JSON. The + # attribute value must respond to +to_json+. + # * custom coder - The attribute value will be serialized + # using the coder's dump(value) method, and will be + # deserialized using the coder's load(string) method. The + # +dump+ method may return +nil+ to serialize the value as +NULL+. # # ==== Options # - # +default+ The default value to use when no value is provided. If this option - # is not passed, the previous default value (if any) will be used. - # Otherwise, the default will be +nil+. + # * +:default+ - The default value to use when no value is provided. If + # this option is not passed, the previous default value (if any) will + # be used. Otherwise, the default will be +nil+. + # + # ==== Examples # - # ==== Example + # ===== Serialize the +preferences+ attribute using YAML # - # # Serialize a preferences attribute using YAML coder. # class User < ActiveRecord::Base # serialize :preferences # end # - # # Serialize preferences using JSON as coder. + # ===== Serialize the +preferences+ attribute using JSON + # # class User < ActiveRecord::Base # serialize :preferences, JSON # end # - # # Serialize preferences as Hash using YAML coder. + # ===== Serialize the +preferences+ +Hash+ using YAML + # # class User < ActiveRecord::Base # serialize :preferences, Hash # end # - # # Serialize preferences using a custom coder. + # ===== Serialize the +preferences+ attribute 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 + # # Serializes an attribute value to a string that will be stored in the database. + # def self.dump(value) + # rot13(ActiveSupport::JSON.dump(value)) # end # - # # reverses the above, turning the serialized string from the database - # # back into its original value + # # Deserializes a string from the database to an attribute value. # def self.load(string) - # ActiveSupport::JSON.decode(string.rot13) + # ActiveSupport::JSON.load(rot13(string)) # end # end # # class User < ActiveRecord::Base # serialize :preferences, Rot13JSON # end + # 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