Class: LedgerSync::Domains::Serializer::Struct
- Inherits:
-
Object
- Object
- LedgerSync::Domains::Serializer::Struct
- Defined in:
- lib/ledger_sync/domains/serializer/struct.rb
Class Method Summary collapse
-
.build(hash, serializer_name, resource:, references:) ⇒ Object
This is the most ruby hackery I ever did Defining Record class that inherits from SimpleDelegator is not enough.
Class Method Details
.build(hash, serializer_name, resource:, references:) ⇒ Object
This is the most ruby hackery I ever did Defining Record class that inherits from SimpleDelegator is not enough. Adding methods through define_method was adding these methods to all objects created through this main class. Specifically address record has an attribute called address, which returned serialized address. This is a same approach, but with dynamic class definition to avoid defining methods in unrelated classes. We are using SimpleDelegator to delegate these methods into OpenStruct passed in. Pure hackery.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ledger_sync/domains/serializer/struct.rb', line 18 def self.build(hash, serializer_name, resource:, references:) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize klass = Class.new(SimpleDelegator) do def self.with_lazy_references(hash, struct_class:, resource:, references:) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize define_method('valid?') { resource.valid? } define_method('errors') { resource.errors } define_method('to_hash') { hash } define_method('class_name') { resource.class.name } define_method('model_name') { resource.model_name } define_method('to_key') { resource.to_key } references.each do |args| if args.type.instance_of?(LedgerSync::Serialization::Type::SerializerReferencesOneType) # rubocop:disable Layout/LineLength define_method("#{args.hash_attribute}_id") do resource.send("#{args.hash_attribute}_id") end end define_method(args.hash_attribute) do Query.const_get( args.type.class.to_s.split('::').last ).new.proxy( serializer: args.type.serializer.new, resource: resource, attribute: args.resource_attribute ) end end new(struct_class.new(hash)) end def to_param id.to_s end def persisted? id.present? end def to_model self end def to_json(*args) JSON.generate(to_hash, *args) end end name = serializer_name.split('::') class_name = name.pop.gsub(/[^0-9a-z ]/i, '').gsub(/.*\KSerializer/, '') struct_name = "#{class_name}Struct" module_name = name.empty? ? Object : Object.const_get(name.join('::')) begin v, $VERBOSE = $VERBOSE, v # module_name.remove_const(struct_name) if module_name.const_defined?(struct_name) module_name.const_set(struct_name, Class.new(OpenStruct)) ensure $VERBOSE = v end klass.with_lazy_references( hash, struct_class: module_name.const_get(struct_name), resource: resource, references: references ) end |