jsonapi_compliable 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Appraisals +4 -0
- data/Gemfile +2 -2
- data/gemfiles/rails_4.gemfile +4 -3
- data/gemfiles/rails_4.gemfile.lock +27 -36
- data/gemfiles/rails_5.gemfile +4 -3
- data/gemfiles/rails_5.gemfile.lock +27 -37
- data/jsonapi_compliable.gemspec +3 -7
- data/lib/jsonapi_compliable/adapters/abstract.rb +25 -0
- data/lib/jsonapi_compliable/adapters/active_record.rb +47 -0
- data/lib/jsonapi_compliable/adapters/active_record_sideloading.rb +119 -0
- data/lib/jsonapi_compliable/adapters/null.rb +21 -0
- data/lib/jsonapi_compliable/base.rb +43 -50
- data/lib/jsonapi_compliable/deserializable.rb +9 -4
- data/lib/jsonapi_compliable/extensions/extra_attribute.rb +1 -5
- data/lib/jsonapi_compliable/query.rb +153 -0
- data/lib/jsonapi_compliable/rails.rb +14 -0
- data/lib/jsonapi_compliable/resource.rb +191 -0
- data/lib/jsonapi_compliable/scope.rb +57 -0
- data/lib/jsonapi_compliable/{scope → scoping}/base.rb +5 -6
- data/lib/jsonapi_compliable/{scope → scoping}/default_filter.rb +3 -3
- data/lib/jsonapi_compliable/scoping/extra_fields.rb +25 -0
- data/lib/jsonapi_compliable/{scope → scoping}/filter.rb +4 -4
- data/lib/jsonapi_compliable/{scope → scoping}/filterable.rb +4 -4
- data/lib/jsonapi_compliable/{scope → scoping}/paginate.rb +6 -6
- data/lib/jsonapi_compliable/scoping/sort.rb +33 -0
- data/lib/jsonapi_compliable/sideload.rb +95 -0
- data/lib/jsonapi_compliable/stats/dsl.rb +7 -16
- data/lib/jsonapi_compliable/stats/payload.rb +6 -14
- data/lib/jsonapi_compliable/util/field_params.rb +6 -8
- data/lib/jsonapi_compliable/util/hash.rb +14 -0
- data/lib/jsonapi_compliable/util/include_params.rb +7 -18
- data/lib/jsonapi_compliable/util/render_options.rb +25 -0
- data/lib/jsonapi_compliable/version.rb +1 -1
- data/lib/jsonapi_compliable.rb +22 -13
- metadata +34 -70
- data/gemfiles/rails_3.gemfile +0 -9
- data/lib/jsonapi_compliable/dsl.rb +0 -90
- data/lib/jsonapi_compliable/scope/extra_fields.rb +0 -35
- data/lib/jsonapi_compliable/scope/sideload.rb +0 -25
- data/lib/jsonapi_compliable/scope/sort.rb +0 -29
- data/lib/jsonapi_compliable/util/pagination.rb +0 -11
- data/lib/jsonapi_compliable/util/scoping.rb +0 -20
| @@ -1,90 +0,0 @@ | |
| 1 | 
            -
            module JsonapiCompliable
         | 
| 2 | 
            -
              class DSL
         | 
| 3 | 
            -
                attr_accessor :sideloads,
         | 
| 4 | 
            -
                  :default_filters,
         | 
| 5 | 
            -
                  :extra_fields,
         | 
| 6 | 
            -
                  :filters,
         | 
| 7 | 
            -
                  :sorting,
         | 
| 8 | 
            -
                  :stats,
         | 
| 9 | 
            -
                  :pagination
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def initialize
         | 
| 12 | 
            -
                  clear!
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def copy
         | 
| 16 | 
            -
                  instance = self.class.new
         | 
| 17 | 
            -
                  instance.sideloads = sideloads.deep_dup
         | 
| 18 | 
            -
                  instance.filters = filters.deep_dup
         | 
| 19 | 
            -
                  instance.default_filters = default_filters.deep_dup
         | 
| 20 | 
            -
                  instance.extra_fields = extra_fields.deep_dup
         | 
| 21 | 
            -
                  instance.sorting = sorting.deep_dup
         | 
| 22 | 
            -
                  instance.pagination = pagination.deep_dup
         | 
| 23 | 
            -
                  instance.stats = stats.deep_dup
         | 
| 24 | 
            -
                  instance
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def clear!
         | 
| 28 | 
            -
                  @sideloads = {}
         | 
| 29 | 
            -
                  @filters = {}
         | 
| 30 | 
            -
                  @default_filters = {}
         | 
| 31 | 
            -
                  @extra_fields = {}
         | 
| 32 | 
            -
                  @stats = {}
         | 
| 33 | 
            -
                  @sorting = nil
         | 
| 34 | 
            -
                  @pagination = nil
         | 
| 35 | 
            -
                end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                def includes(whitelist: nil, &blk)
         | 
| 38 | 
            -
                  whitelist = JSONAPI::IncludeDirective.new(whitelist) if whitelist
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                  @sideloads = {
         | 
| 41 | 
            -
                    whitelist: whitelist,
         | 
| 42 | 
            -
                    custom_scope: blk
         | 
| 43 | 
            -
                  }
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                def allow_filter(name, *args, &blk)
         | 
| 47 | 
            -
                  opts = args.extract_options!
         | 
| 48 | 
            -
                  aliases = [name, opts[:aliases]].flatten.compact
         | 
| 49 | 
            -
                  @filters[name.to_sym] = {
         | 
| 50 | 
            -
                    aliases: aliases,
         | 
| 51 | 
            -
                    if: opts[:if],
         | 
| 52 | 
            -
                    filter: blk
         | 
| 53 | 
            -
                  }
         | 
| 54 | 
            -
                end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                def allow_stat(symbol_or_hash, &blk)
         | 
| 57 | 
            -
                  dsl = Stats::DSL.new(symbol_or_hash)
         | 
| 58 | 
            -
                  dsl.instance_eval(&blk) if blk
         | 
| 59 | 
            -
                  @stats[dsl.name] = dsl
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                def default_filter(name, &blk)
         | 
| 63 | 
            -
                  @default_filters[name.to_sym] = {
         | 
| 64 | 
            -
                    filter: blk
         | 
| 65 | 
            -
                  }
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def sort(&blk)
         | 
| 69 | 
            -
                  @sorting = blk
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                def paginate(&blk)
         | 
| 73 | 
            -
                  @pagination = blk
         | 
| 74 | 
            -
                end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
                def extra_field(field, &blk)
         | 
| 77 | 
            -
                  @extra_fields[field.keys.first] ||= []
         | 
| 78 | 
            -
                  @extra_fields[field.keys.first] << {
         | 
| 79 | 
            -
                    name: field.values.first,
         | 
| 80 | 
            -
                    proc: blk
         | 
| 81 | 
            -
                  }
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
             | 
| 84 | 
            -
                def stat(attribute, calculation)
         | 
| 85 | 
            -
                  stats_dsl = @stats[attribute] || @stats[attribute.to_sym]
         | 
| 86 | 
            -
                  raise Errors::StatNotFound.new(attribute, calculation) unless stats_dsl
         | 
| 87 | 
            -
                  stats_dsl.calculation(calculation)
         | 
| 88 | 
            -
                end
         | 
| 89 | 
            -
              end
         | 
| 90 | 
            -
            end
         | 
| @@ -1,35 +0,0 @@ | |
| 1 | 
            -
            module JsonapiCompliable
         | 
| 2 | 
            -
              class Scope::ExtraFields < Scope::Base
         | 
| 3 | 
            -
                def apply
         | 
| 4 | 
            -
                  each_extra_field do |extra_field|
         | 
| 5 | 
            -
                    @scope = extra_field[:proc].call(@scope)
         | 
| 6 | 
            -
                  end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                  @scope
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                private
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                def each_extra_field
         | 
| 14 | 
            -
                  dsl.extra_fields.each_pair do |namespace, extra_fields|
         | 
| 15 | 
            -
                    extra_fields.each do |extra_field|
         | 
| 16 | 
            -
                      if requested_extra_field?(namespace, extra_field[:name])
         | 
| 17 | 
            -
                        yield extra_field
         | 
| 18 | 
            -
                      end
         | 
| 19 | 
            -
                    end
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                def extra_fields
         | 
| 24 | 
            -
                  params[:extra_fields] || {}
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                def requested_extra_field?(namespace, field)
         | 
| 28 | 
            -
                  if namespaced = extra_fields[namespace]
         | 
| 29 | 
            -
                    namespaced.include?(field)
         | 
| 30 | 
            -
                  else
         | 
| 31 | 
            -
                    false
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
            end
         | 
| @@ -1,25 +0,0 @@ | |
| 1 | 
            -
            module JsonapiCompliable
         | 
| 2 | 
            -
              class Scope::Sideload < Scope::Base
         | 
| 3 | 
            -
                def apply
         | 
| 4 | 
            -
                  params[:include] ? super : @scope
         | 
| 5 | 
            -
                end
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                def custom_scope
         | 
| 8 | 
            -
                  dsl.sideloads[:custom_scope]
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def apply_standard_scope
         | 
| 12 | 
            -
                  @scope.includes(scrubbed)
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def apply_custom_scope
         | 
| 16 | 
            -
                  custom_scope.call(@scope, scrubbed)
         | 
| 17 | 
            -
                end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                private
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def scrubbed
         | 
| 22 | 
            -
                  Util::IncludeParams.scrub(controller)
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
            end
         | 
| @@ -1,29 +0,0 @@ | |
| 1 | 
            -
            module JsonapiCompliable
         | 
| 2 | 
            -
              class Scope::Sort < Scope::Base
         | 
| 3 | 
            -
                def custom_scope
         | 
| 4 | 
            -
                  dsl.sorting
         | 
| 5 | 
            -
                end
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                def apply_standard_scope
         | 
| 8 | 
            -
                  @scope.order(attribute => direction)
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def apply_custom_scope
         | 
| 12 | 
            -
                  custom_scope.call(@scope, attribute, direction)
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                private
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                def sort_param
         | 
| 18 | 
            -
                  @sort_param ||= (params[:sort] || @controller.default_sort)
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def direction
         | 
| 22 | 
            -
                  sort_param.starts_with?('-') ? :desc : :asc
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                def attribute
         | 
| 26 | 
            -
                  sort_param.dup.sub('-', '').to_sym
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
            end
         | 
| @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            module JsonapiCompliable
         | 
| 2 | 
            -
              module Util
         | 
| 3 | 
            -
                class Scoping
         | 
| 4 | 
            -
                  def self.apply?(controller, object, force)
         | 
| 5 | 
            -
                    return false if force == false
         | 
| 6 | 
            -
                    return true if controller._jsonapi_scope.nil? && object.is_a?(ActiveRecord::Relation)
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                    already_scoped = !!controller._jsonapi_scope
         | 
| 9 | 
            -
                    is_activerecord = object.is_a?(ActiveRecord::Base)
         | 
| 10 | 
            -
                    is_activerecord_array = object.is_a?(Array) && object[0].is_a?(ActiveRecord::Base)
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                    if [already_scoped, is_activerecord, is_activerecord_array].any?
         | 
| 13 | 
            -
                      false
         | 
| 14 | 
            -
                    else
         | 
| 15 | 
            -
                      true
         | 
| 16 | 
            -
                    end
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
            end
         |