Skip to content

Instantly share code, notes, and snippets.

@joshmn
Last active November 23, 2020 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshmn/dc2c2f7e5440a7a71574f97c8b95cc4b to your computer and use it in GitHub Desktop.
Save joshmn/dc2c2f7e5440a7a71574f97c8b95cc4b to your computer and use it in GitHub Desktop.
simple serializer pattern
class ApplicationSerializer
attr_reader :object
def initialize(object, options = {})
@object = object
@options = options
end
def to_json
JSON.generate(as_json)
end
def as_json
raise NotImplementedError
end
end
module FancyAttributeDSL
def self.included(klass)
klass.extend ClassMethods
end
def as_json
hash = {}
self.class._serialized_attributes.each do |attr, block|
hash[attr] = read_attribute_for_serialization(attr, &block)
end
hash
end
private
def read_attribute_for_serialization(attr, &block)
if block
instance_eval(&block)
elsif respond_to?(attr)
send(attr)
else
object.send(attr)
end
end
module ClassMethods
def _serialized_attributes
@_serialized_attributes ||= {}
end
def attributes(*keys)
keys.each { |key| _serialized_attributes[key] = nil }
end
def attribute(key, &block)
_serialized_attributes[key] = block
end
end
end
@joshmn
Copy link
Author

joshmn commented Nov 23, 2020

Usage:

class PostSerializer < ApplicationSerializer
  include FancyAttributeDSL

  attributes :id, :body

  attribute :new_title do
    "new fancy title: #{object.title}"
  end

  attribute :death do 
    "#{death}, because GC"
  end

  private
  
  def death 
    "death is inevitable"
  end
end

post = OpenStruct.new(id: 1, title: "hi", body: "cool")
puts FancyPostSerializer.new(post).to_json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment