jpie 2.1.2 → 2.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d80d347b9e33b07e48e743d38c6e8dce2423888c49f8b727b52c3f093b835d45
4
- data.tar.gz: befcf097a0471378554ec98e328546be5426d812ac48ea2428da42b71221b783
3
+ metadata.gz: 23a1e7f0dd69ee73d5a8f684ac39005fca7081222517086e5f708ffd8ca7815b
4
+ data.tar.gz: c2ae85e3db1522db8891a6ec0cba3956af94993e1658bdbe0e2a517af9954740
5
5
  SHA512:
6
- metadata.gz: b01847d08978c2df2e270e36e231bbf21cfc93824a1c9519c2b982d819777050a21df3252183819f218c4d44b420f8161f9857c5add05900a663f11be87405b6
7
- data.tar.gz: 8c89e6f2502308dddf7b72edffd8e58603bf664b7b6401ab9b7d100ad55024f25f2df46791b45d0097b6647a1de1fda7ef17363cc8ec83fd6f8e3691e2598302
6
+ metadata.gz: 2fa70259c383d4f694f0071384f3b9a8f6f46e3b26765644bbaa45045c4be86454ba9a934b1ec79f9571f1846ae54cdd3b61ec439ba9c000155ee74feaeef1f8
7
+ data.tar.gz: 3b00c7a05a52bc30b81109a09e95c65cdd6602facba9e8c92b0011ca3a6b3cc0eecb4da2b15704a5d2df03325b70f3aed474988034cefdd7111089815eab8e39
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jpie (2.1.2)
4
+ jpie (2.1.4)
5
5
  actionpack (~> 8.1, >= 8.1.0)
6
6
  pg_query (>= 4)
7
7
  prosopite (>= 1)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json_api/support/sort_value_comparison"
4
+
3
5
  module JSONAPI
4
6
  module Relationships
5
7
  module Sorting
@@ -75,11 +77,7 @@ module JSONAPI
75
77
  end
76
78
 
77
79
  def compare_values(value_a, value_b)
78
- return 0 if value_a.nil? && value_b.nil?
79
- return -1 if value_a.nil?
80
- return 1 if value_b.nil?
81
-
82
- value_a <=> value_b
80
+ JSONAPI::Support::SortValueComparison.compare(value_a, value_b)
83
81
  end
84
82
 
85
83
  def validate_sort_param
@@ -21,26 +21,15 @@ module JSONAPI
21
21
  check_filter_parts(parts, @resource_class, model_class)
22
22
  end
23
23
 
24
- def check_filter_parts(parts, res_cls, mod_cls, allow_related: false)
24
+ def check_filter_parts(parts, res_cls, mod_cls)
25
25
  return false if parts.empty?
26
- return single_filter_valid?(parts.first, res_cls, mod_cls, allow_related) if parts.length == 1
26
+ return single_filter_valid?(parts.first, res_cls) if parts.length == 1
27
27
 
28
28
  check_nested_filter(parts, res_cls, mod_cls)
29
29
  end
30
30
 
31
- def single_filter_valid?(name, res_cls, mod_cls, allow_related)
32
- return true if res_cls.permitted_filters.map(&:to_s).include?(name)
33
- return false unless allow_related
34
-
35
- related_column_valid?(name, mod_cls)
36
- end
37
-
38
- def related_column_valid?(name, mod_cls)
39
- col = parse_column_filter(name)
40
- return true if col && mod_cls.column_for_attribute(col[:column])
41
- return true if mod_cls.column_names.include?(name)
42
-
43
- mod_cls.respond_to?(name.to_sym)
31
+ def single_filter_valid?(name, res_cls)
32
+ res_cls.permitted_filters.map(&:to_s).include?(name)
44
33
  end
45
34
 
46
35
  def check_nested_filter(parts, res_cls, mod_cls)
@@ -59,7 +48,7 @@ module JSONAPI
59
48
  rel_res = JSONAPI::Resource.resource_for_model(rel_mod)
60
49
  return false unless rel_res
61
50
 
62
- check_filter_parts(parts, rel_res, rel_mod, allow_related: true)
51
+ check_filter_parts(parts, rel_res, rel_mod)
63
52
  end
64
53
 
65
54
  def filter_rel_allowed?(res_cls, rel)
@@ -19,6 +19,7 @@ module JSONAPI
19
19
  def scope_with_includes(scope)
20
20
  includes = parse_include_param
21
21
  return scope unless includes.any?
22
+ return scope if scope.is_a?(Array)
22
23
 
23
24
  inc_hash = includes_to_hash(includes)
24
25
  hash_contains_polymorphic?(inc_hash, model_class) ? scope.preload(inc_hash) : scope.includes(inc_hash)
@@ -13,8 +13,6 @@ module JSONAPI
13
13
  end
14
14
 
15
15
  def normalize_filter_value_for_model(model, column, raw_value)
16
- return nil unless column
17
-
18
16
  value = raw_value.is_a?(Array) ? raw_value.first : raw_value
19
17
  return nil if value.nil?
20
18
 
@@ -39,6 +37,19 @@ module JSONAPI
39
37
  lower_attr.matches(pattern.downcase)
40
38
  end
41
39
 
40
+ def apply_column_filter(scope, model, filter_name, raw_value)
41
+ column_filter = parse_column_filter(filter_name)
42
+ return nil unless column_filter
43
+ return nil unless model.column_names.include?(column_filter[:column])
44
+
45
+ column = model.column_for_attribute(column_filter[:column])
46
+ value = normalize_filter_value_for_model(model, column, raw_value)
47
+ return nil unless value
48
+
49
+ condition = build_condition(model, column, value, column_filter[:operator])
50
+ condition ? apply_condition(scope, condition) : nil
51
+ end
52
+
42
53
  def apply_condition(scope, condition)
43
54
  scope.where(condition)
44
55
  end
@@ -81,40 +81,12 @@ module JSONAPI
81
81
  def apply_filter_on_model(scope, target_model, target_resource, filter_name, filter_value)
82
82
  return scope if empty_filter_value?(filter_value)
83
83
 
84
- apply_column_operator_filter(scope, target_model, filter_name, filter_value) ||
85
- apply_direct_column_filter(scope, target_model, filter_name, filter_value) ||
84
+ apply_column_filter(scope, target_model, filter_name, filter_value) ||
86
85
  apply_scope_method_filter(scope, target_model, target_resource, filter_name, filter_value) ||
87
86
  scope
88
87
  end
89
88
 
90
- def apply_column_operator_filter(scope, target_model, filter_name, filter_value)
91
- column_filter = parse_column_filter(filter_name)
92
- return nil unless column_filter
93
-
94
- column = target_model.column_for_attribute(column_filter[:column])
95
- return nil unless column
96
-
97
- value = normalize_filter_value_for_model(target_model, column, filter_value)
98
- return nil unless value
99
-
100
- condition = build_condition(target_model, column, value, column_filter[:operator])
101
- condition ? apply_condition(scope, condition) : nil
102
- end
103
-
104
- def apply_direct_column_filter(scope, target_model, filter_name, filter_value)
105
- return nil unless target_model.column_names.include?(filter_name)
106
-
107
- scope.where(target_model.table_name => { filter_name => filter_value })
108
- end
109
-
110
- def apply_scope_method_filter(scope, target_model, target_resource, filter_name, filter_value)
111
- if target_model.respond_to?(filter_name.to_sym)
112
- return try_scope_method(scope, target_model, filter_name,
113
- filter_value,)
114
- end
115
-
116
- return nil unless target_resource
117
- return nil unless target_resource.permitted_filters.map(&:to_s).include?(filter_name)
89
+ def apply_scope_method_filter(scope, target_model, _target_resource, filter_name, filter_value)
118
90
  return nil unless target_model.respond_to?(filter_name.to_sym)
119
91
 
120
92
  try_scope_method(scope, target_model, filter_name, filter_value)
@@ -19,36 +19,8 @@ module JSONAPI
19
19
  def apply_regular_filter(scope, filter_name, filter_value)
20
20
  return scope if empty_filter_value?(filter_value)
21
21
 
22
- column_filter = parse_column_filter(filter_name)
23
- if column_filter
24
- apply_column_filter(scope, column_filter, filter_value)
25
- else
22
+ apply_column_filter(scope, model_class, filter_name, filter_value) ||
26
23
  apply_scope_fallback(scope, filter_name, filter_value)
27
- end
28
- end
29
-
30
- def apply_column_filter(scope, column_filter, raw_value)
31
- condition = build_column_condition(column_filter, raw_value)
32
- condition ? apply_condition(scope, condition) : scope
33
- rescue StandardError => e
34
- log_filter_error(column_filter, column_filter[:operator], e)
35
- scope
36
- end
37
-
38
- def build_column_condition(column_filter, raw_value)
39
- column = model_class.column_for_attribute(column_filter[:column])
40
- return nil unless column
41
-
42
- value = normalize_filter_value_for_model(model_class, column, raw_value)
43
- return nil if value.nil?
44
-
45
- build_condition(model_class, column, value, column_filter[:operator])
46
- end
47
-
48
- def log_filter_error(column_filter, operator, error)
49
- return unless defined?(Rails.logger)
50
-
51
- Rails.logger.warn("Filter error for #{column_filter[:column]}_#{operator}: #{error.class} - #{error.message}")
52
24
  end
53
25
 
54
26
  def apply_scope_fallback(scope, filter_name, filter_value)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json_api/support/sort_value_comparison"
4
+
3
5
  module JSONAPI
4
6
  module Support
5
7
  module Sorting
@@ -77,11 +79,7 @@ module JSONAPI
77
79
  end
78
80
 
79
81
  def compare_values(value_a, value_b)
80
- return 0 if value_a.nil? && value_b.nil?
81
- return -1 if value_a.nil?
82
- return 1 if value_b.nil?
83
-
84
- value_a <=> value_b
82
+ SortValueComparison.compare(value_a, value_b)
85
83
  end
86
84
  end
87
85
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JSONAPI
4
+ module Support
5
+ # Compares two values for stable sort ordering. Ruby 3.4+ TrueClass#<=> returns nil
6
+ # when operands differ (true <=> false), so booleans are normalized before <=>.
7
+ module SortValueComparison
8
+ module_function
9
+
10
+ def compare(value_a, value_b)
11
+ return 0 if value_a.nil? && value_b.nil?
12
+ return -1 if value_a.nil?
13
+ return 1 if value_b.nil?
14
+
15
+ value_a = value_a ? 1 : 0 if value_a in TrueClass | FalseClass
16
+ value_b = value_b ? 1 : 0 if value_b in TrueClass | FalseClass
17
+
18
+ result = value_a <=> value_b
19
+ return result unless result.nil?
20
+
21
+ detail = "#{value_a.class.name} (#{value_a.inspect}), #{value_b.class.name} (#{value_b.inspect})"
22
+ raise ArgumentError, "incomparable sort values: #{detail}"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONAPI
4
- VERSION = "2.1.2"
4
+ VERSION = "2.1.4"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jpie
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Kampp
@@ -192,6 +192,7 @@ files:
192
192
  - lib/json_api/support/resource_identifier.rb
193
193
  - lib/json_api/support/responders.rb
194
194
  - lib/json_api/support/sort_parsing.rb
195
+ - lib/json_api/support/sort_value_comparison.rb
195
196
  - lib/json_api/support/type_conversion.rb
196
197
  - lib/json_api/testing.rb
197
198
  - lib/json_api/testing/rspec.rb