class TinySerializer
Simple DSL
for converting objects to Hashes, which is mostly API-compatible with ActiveModel::Serializer. The Hashes can be rendered as JSON by Rails.
I have also added some fast_jsonapi API parameters that do nothing, to ease later transition to that library.
Usage¶ ↑
# my_object.rb MyObject = Struct.new(:id, :first_name, :last_name, :date) do def parent; nil; end def sub_record; nil; end def related_items; []; end end # my_object_serializer.rb class MyObjectSerializer < TinySerializer attributes :id, :first_name, :last_name, :date belongs_to :parent, serializer: ParentSerializer has_one :sub_record # serializer will be inferred to be SubRecordSerializer has_many :related_items, serializer: RelatedItemSerializer attribute :full_name do "#{object.first_name} #{object.last_name}" end end # my_objects_controller.rb def show @my_object = MyObject.new(1, "Fred", "Flintstone", Date.new(2000, 1, 1)) render json: MyObjectSerializer.new(@my_object).serialize end
RailsExtensions
¶ ↑
The RailsExtensions
module is automatically prepended when TinySerializer
is used in a Rails app. It defines some small convenience instance methods.
Constants
- VERSION
Attributes
Optional logger object. Defaults to Rails.logger in a Rails app.
The object to serialize as a Hash
Hash of data to be passed to blocks
Public Class Methods
Check if object
is a collection.
# File lib/tiny_serializer.rb, line 136 def is_collection?(object) object.respond_to?(:each) && !object.respond_to?(:each_pair) end
Create a new serializer instance.
- object
-
The object to serialize. Can be a single object or a collection of objects.
# File lib/tiny_serializer.rb, line 76 def initialize(object, options = {}) @object = object @options = options end
The same as:
TinySerializer.new(object).serializable_hash
# File lib/tiny_serializer.rb, line 124 def serialize(object, options = {}) new(object, options).serializable_hash end
Same as serialize
, but raises ArgumentError if `collection` doesn't appear to be a collection.
# File lib/tiny_serializer.rb, line 130 def serialize_each(collection) raise ArgumentError, "collection does not appear to be a collection" unless is_collection?(collection) new(collection).serializable_hash end
Public Instance Methods
Serialize object
as a Hash, then call as_json
on the Hash, which will convert keys to Strings.
There shouldn't be a need to call this, but we implement it to fully support ActiveSupport's magic JSON protocols.
# File lib/tiny_serializer.rb, line 101 def as_json(_ = nil) serializable_hash.as_json end
Return true if object
is a collection.
# File lib/tiny_serializer.rb, line 115 def collection? self.class.is_collection?(@object) end
Serialize object
as a Hash with Symbol keys. Returns nil if object
is nil.
# File lib/tiny_serializer.rb, line 83 def serializable_hash(_ = nil) return serialize_single_object_to_hash unless collection? json = [] @object.each do |object| json << self.class.new(object, @options).serializable_hash end json end
Serialize object
to a JSON String.
Calls serializable_hash
, then call to_json
on the resulting Hash, converting it to a String using the automatic facilities for doing so from ActiveSupport.
# File lib/tiny_serializer.rb, line 110 def to_json(_ = nil) serializable_hash.to_json end
Private Instance Methods
# File lib/tiny_serializer.rb, line 162 def get_attribute(name, block) if block instance_exec(@object, @options, &block) else @object.public_send(name) end end
Get the collection from object
or block, or [] if nil.
# File lib/tiny_serializer.rb, line 206 def get_collection(name, block) if block instance_exec(@object, @options, &block) else @object.public_send(name) end || [] end
Internal algorithm to convert any object to a valid JSON string, scalar, object, array, etc. All objects are passed through this function after they are retrieved from object
. Currently just calls as_json
.
# File lib/tiny_serializer.rb, line 173 def serialize_attribute(raw_value, is_id = false) if is_id && coerce_ids_to_string? serialize_id(raw_value) else raw_value.as_json end end
# File lib/tiny_serializer.rb, line 155 def serialize_attributes(hash) self.class.attributes.each do |name, key, is_id, block| raw_value = get_attribute(name, block) hash[key] = serialize_attribute(raw_value, is_id) end end
# File lib/tiny_serializer.rb, line 192 def serialize_collections(hash) self.class.collections.each do |collection_name, key, serializer, block| collection = get_collection(collection_name, block) json_array = [] collection.each do |object| json_array << serializer.new(object, @options).serializable_hash end hash[key] = json_array end end
# File lib/tiny_serializer.rb, line 181 def serialize_id(id) id && id.to_s end
Private serialization implementation for a single object. @object must be a single object.
# File lib/tiny_serializer.rb, line 145 def serialize_single_object_to_hash return nil if @object.nil? hash = {} serialize_attributes(hash) serialize_sub_records(hash) serialize_collections(hash) hash end
# File lib/tiny_serializer.rb, line 185 def serialize_sub_records(hash) self.class.sub_records.each do |name, key, serializer, block| record = get_attribute(name, block) hash[key] = serializer.new(record, @options).serializable_hash end end