lib/json_api/resources/concerns/attributes_dsl.rb



# frozen_string_literal: true

module JSONAPI
  module Resources
    module AttributesDsl
      extend ActiveSupport::Concern

      class_methods do
        def attributes(*attrs)
          @attributes ||= []
          @attributes.concat(attrs.map(&:to_sym))
          @attributes.uniq!
        end

        def creatable_fields(*fields)
          @creatable_fields ||= []
          @creatable_fields.concat(fields.map(&:to_sym))
          @creatable_fields.uniq!
        end

        def updatable_fields(*fields)
          @updatable_fields ||= []
          @updatable_fields.concat(fields.map(&:to_sym))
          @updatable_fields.uniq!
        end
      end

      module FieldResolution
        def permitted_attributes
          declared_attributes = instance_variable_defined?(:@attributes)
          attrs = @attributes || []
          attrs = superclass.permitted_attributes + attrs if should_inherit_attributes?(declared_attributes)
          attrs.uniq
        end

        def permitted_creatable_fields
          resolve_field_list(:@creatable_fields, :permitted_creatable_fields)
        end

        def permitted_updatable_fields
          resolve_field_list(:@updatable_fields, :permitted_updatable_fields)
        end

        def resolve_field_list(ivar, method)
          return (instance_variable_get(ivar) || []).uniq if instance_variable_defined?(ivar)
          return superclass.public_send(method).uniq if inherits_field?(ivar, method)

          permitted_attributes.uniq
        end

        def inherits_field?(ivar, method)
          superclass != JSONAPI::Resource &&
            superclass.respond_to?(method) &&
            superclass.instance_variable_defined?(ivar)
        end

        def should_inherit_attributes?(declared_attributes)
          !declared_attributes &&
            superclass != JSONAPI::Resource &&
            superclass.respond_to?(:permitted_attributes)
        end
      end

      included do
        extend FieldResolution
      end
    end
  end
end