# frozen_string_literal: true # The IncludedResourceParams class is responsible for parsing a string containing # a comma separated list of associated resources to include with a request. See # http://jsonapi.org/format/#fetching-includes for additional details although # this is not required knowledge for the task at hand. # # Our API requires specific inclusion of related resourses - that is we do NOT # want to support wildcard inclusion (e.g. `foo.*`) # # The IncludedResourceParams class has three public methods making up its API. # # [included_resources] # returns an array of non-wildcard included elements. # [has_included_resources?] # Returns true if our supplied param has included resources, false otherwise. # [model_includes] # returns an array suitable to supply to ActiveRecord's `includes` method # (http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations) # The included_resources should be transformed as specified in the unit tests # included herein. # # All three public methods have unit tests written below that must pass. You are # free to add additional classes/modules as necessary and/or private methods # within the IncludedResourceParams class. # # Feel free to use the Ruby standard libraries available in your # solution. # class IncludedResourceParams def initialize(include_param) @include_param = include_param end ## # Does our IncludedResourceParams instance actually have any valid included # resources after parsing? # # @return [Boolean] whether this instance has included resources def parse array = @include_param ? @include_param.split(',') : [] array = array.reject do |element| element.include? '*' end end def has_included_resources? !parse.empty? end ## # Fetches the included resourcs as an Array containing only non-wildcard # resource specifiers. # # @example nil # IncludedResourceParams.new(nil).included_resources => [] # # @example "foo,foo.bar,baz.*" # IncludedResourceParams.new("foo,bar,baz.*").included_resources => ["foo", "bar"] # # @return [Array] an Array of Strings parsed from the include param with # wildcard includes removed def included_resources parse # TODO: implement me end ## # Converts the resources to be included from their JSONAPI representation to # a structure compatible with ActiveRecord's `includes` methods. This can/should # be an Array in all cases. Does not do any verification that the resources # specified for inclusion are actual ActiveRecord classes. # # @example nil # IncludedResourceParams.new(nil).model_includes => [] # # @example "foo" # IncludedResourceParams.new("foo").model_includes => [:foo] # # @see Following unit tests # # @return [Array] an Array of Symbols and/or Hashes compatible with ActiveRecord # `includes` def model_includes # TODO: implement me ret = included_resources.map do |element| if (element.include? '.') to_active_record element.split '.' else element.to_sym end end end # rec function that convert to nested object def to_active_record(elements ); if elements.length == 1 return [elements[0].to_sym] end {elements[0].to_sym => to_active_record(elements[1..elements.length])} end end