Sha256: 749a462915633f654d19bb7e7bc60e1d7929d8e008b81e5d694f0751fc0a3b48

Contents?: true

Size: 1.49 KB

Versions: 4

Compression:

Stored size: 1.49 KB

Contents

require 'active_record'

module Fields
  module Serializer
    module ActiveRecord
      extend ActiveSupport::Concern

      class_methods do
        # Convert a list of fields (json_api notation) in a list of associations to be
        # added to a ActiveRecord Model.includes call
        #
        # Example:
        #
        #  BoilerPack.fields_to_includes("id,boiler.gas_safe_code") #=> ["boiler"]
        #
        def fields_to_includes(fields)
          flatten_fields = Array(fields).map { |str| str.to_s.split(",").map(&:strip) }.flatten
          nested_fields  = flatten_fields.map { |field| nested_field(field.split(".")) }.compact
          nested_fields.inject([{}]) do |result, attribute_structure|
            if attribute_structure.is_a?(Hash)
              result.first.deep_merge!(attribute_structure) { |_, u, v| u == v ? u : [u, v] }
            else
              result << attribute_structure unless result.first.dig(attribute_structure) || result.include?(attribute_structure)
            end
            result
          end.map(&:presence).compact
        end

        def nested_field(attribute_stack)
          parent = attribute_stack.first
          return unless association?(parent)
          parent_klass = reflections[parent].class_name.constantize
          { parent => parent_klass.nested_field(attribute_stack[1..-1]) }.compact.presence || parent
        end

        private

        def association?(key)
          reflections.keys.include?(key)
        end
      end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
fields-serializer-0.3.1 lib/fields/serializer/active_record.rb
fields-serializer-0.3.0 lib/fields/serializer/active_record.rb
fields-serializer-0.2.4 lib/fields/serializer/active_record.rb
fields-serializer-0.2.3 lib/fields/serializer/active_record.rb