<commit_before>module JSONAPIonify::Api
  module Resource::Defaults::RequestContexts
    extend ActiveSupport::Concern

    included do
      context(:request_body, readonly: true) do |context|
        context.request.body.read
      end

      context(:request_object, readonly: true) do |context|
        JSONAPIonify.parse(context.request_body).as(:client).tap do |input|
          error_now(:request_object_invalid, context, input) unless input.validate
        end
      end

      context(:id, readonly: true) do |context|
        context.request.env['jsonapionify.id']
      end

      context(:request_id) do |context|
        context.request_data[:id]
      end

      context(:request_attributes, readonly: true) do |context|
        should_error = false

        request_attributes = context.request_data.fetch(:attributes) do
          error_now :attributes_missing
        end

        # Check for required attributes
        self.attributes.each do |attr|
          next unless attr.required_for_action?(action_name)
          unless request_attributes.has_key?(attr.name)
            error :attribute_required, attr.name
            should_error = true
          end
        end

        request_attributes.each_with_object({}) do |(attr, v), attributes|
          resource_attribute = self.attributes.find { |a| a.name == attr }
          is_writable = !!resource_attribute&.write?
          is_actionable = !!resource_attribute&.supports_action?(action_name)
          unless is_writable && is_actionable
            error :attribute_not_permitted, attr
            should_error = true
          end

          begin
            attributes[attr] = resource_attribute.type.load(v)
          rescue JSONAPIonify::Types::LoadError
            error :attribute_type_error, attr
            should_error = true
          end
        end.tap do
          raise Errors::RequestError if should_error
        end

      end

      context(:request_instances, readonly: true) do |context|
        should_error = false
        data         = context.request_data
        instances    = data.map.each_with_index do |item, i|
          begin
            find_instance item, pointer: "data/#{i}"
          rescue Errors::RequestError<commit_msg>Attempt to resolve attributes on update if they are required<commit_after>module JSONAPIonify::Api
  module Resource::Defaults::RequestContexts
    extend ActiveSupport::Concern

    included do
      context(:request_body, readonly: true) do |context|
        context.request.body.read
      end

      context(:request_object, readonly: true) do |context|
        JSONAPIonify.parse(context.request_body).as(:client).tap do |input|
          error_now(:request_object_invalid, context, input) unless input.validate
        end
      end

      context(:id, readonly: true) do |context|
        context.request.env['jsonapionify.id']
      end

      context(:request_id) do |context|
        context.request_data[:id]
      end

      context(:request_attributes, readonly: true) do |context|
        should_error = false

        request_attributes =
          context.request_data.fetch(:attributes) do
            error_now :attributes_missing
          end

        # Check for required attributes
        self.attributes.each do |attr|
          next unless attr.required_for_action?(action_name)
          if attr.read? || context.id
            example_id   = self.build_id(context.instance)
            next unless attr.resolve(
              context.instance, context, example_id: example_id
            ).nil?
          end
          unless request_attributes.has_key?(attr.name)
            error :attribute_required, attr.name
            should_error = true
          end
        end

        request_attributes.each_with_object({}) do |(attr, v), attributes|
          resource_attribute = self.attributes.find { |a| a.name == attr }
          is_writable        = !!resource_attribute&.write?
          is_actionable      = !!resource_attribute&.supports_action?(action_name)
          unless is_writable && is_actionable
            error :attribute_not_permitted, attr
            should_error = true
          end

          begin
            attributes[attr] = resource_attribute.type.load(v)
          rescue JSONAPIonify::Types::LoadError
            error :attribute_type_error, attr
            should_error = true
          end
        end.tap do
          raise Errors::RequestError if should_error
        end

      end

      context(:request_instances, readonly: true) do |context|
        should_error = false
        data         = context.request_data
        instances    = data.map.each_with_index do |item, i|
          begin
            find_instance item, pointer: "data/#{i}"
          rescue Errors::RequestError
{'fraction_non_alphanumeric': 0.08060820662362007, 'fraction_numerical': 0.0, 'mean_word_length': 2.2380310182063385, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1369437', 'n_tokens_mistral': 1272, 'n_tokens_neox': 1252, 'n_words': 296}