Created
May 14, 2022 17:50
-
-
Save vol1ura/7952afcf1c428fc014939d29ab3efa40 to your computer and use it in GitHub Desktop.
A simple "replacement" for `grape-entity` gem for small API projects. Allows you to create custom classes, inherit from them and get representations of both individual objects and their collections.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Entities | |
# Fabric class to build object representation classes | |
class Base | |
def self.represent(...) | |
new(...).represent | |
end | |
def self.represent_collection(collection, options = {}) | |
collection.map { |object| represent(object, options) } | |
end | |
def initialize(object, exposed_keys, options) | |
@object = object | |
@model_keys = exposed_keys.keys | |
@mapping = exposed_keys | |
@options = options | |
end | |
def represent | |
@options.key?(:root) ? { @options[:root] => body } : body | |
end | |
private | |
attr_reader :object | |
def body | |
@body ||= model_keys.index_with { |key| build_value(key) }.compact | |
end | |
def model_keys | |
@model_keys &= Array(@options[:only]) if @options.key? :only | |
@model_keys -= Array(@options[:except]) if @options.key? :except | |
@model_keys | |
end | |
def build_value(key) | |
key_method = @mapping.dig(key, :as).presence || key | |
value = key_method.is_a?(Proc) ? call_to_proc(key_method) : send_to_self(key_method) | |
return if @mapping.dig(key, :expose_nil) == false && value.blank? | |
value = @mapping[key][:format_with].to_proc.call(value) if @mapping.dig(key, :format_with) | |
value | |
end | |
def send_to_self(key_method) | |
respond_to?(key_method, true) ? send(key_method) : object.public_send(key_method) | |
end | |
def call_to_proc(key_method) | |
key_method.arity.zero? ? key_method.call : key_method.call(object) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment