ransack 6.0.1 → 6.1.0
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/README.md +43 -68
- data/lib/ransack/active_record/context.rb +207 -75
- data/lib/ransack/active_record/join_association.rb +8 -17
- data/lib/ransack/active_record/join_dependency.rb +163 -9
- data/lib/ransack/configuration.rb +25 -2
- data/lib/ransack/context.rb +55 -7
- data/lib/ransack/errors.rb +13 -0
- data/lib/ransack/invalid_search_error.rb +3 -3
- data/lib/ransack/locale/ar.yml +35 -0
- data/lib/ransack/locale/az.yml +36 -1
- data/lib/ransack/locale/bg.yml +35 -0
- data/lib/ransack/locale/ca.yml +36 -1
- data/lib/ransack/locale/cs.yml +35 -0
- data/lib/ransack/locale/da.yml +35 -0
- data/lib/ransack/locale/de.yml +36 -1
- data/lib/ransack/locale/el.yml +36 -1
- data/lib/ransack/locale/en.yml +35 -0
- data/lib/ransack/locale/es.yml +36 -1
- data/lib/ransack/locale/fa.yml +35 -0
- data/lib/ransack/locale/fi.yml +35 -0
- data/lib/ransack/locale/fr.yml +35 -0
- data/lib/ransack/locale/hu.yml +35 -0
- data/lib/ransack/locale/id.yml +35 -0
- data/lib/ransack/locale/it.yml +35 -0
- data/lib/ransack/locale/ja.yml +35 -0
- data/lib/ransack/locale/ko.yml +35 -0
- data/lib/ransack/locale/nl.yml +35 -0
- data/lib/ransack/locale/pt-BR.yml +35 -0
- data/lib/ransack/locale/ro.yml +35 -0
- data/lib/ransack/locale/ru.yml +35 -0
- data/lib/ransack/locale/sk.yml +35 -0
- data/lib/ransack/locale/sv.yml +35 -0
- data/lib/ransack/locale/tr.yml +36 -1
- data/lib/ransack/locale/uk.yml +35 -0
- data/lib/ransack/locale/zh-CN.yml +35 -0
- data/lib/ransack/locale/zh-TW.yml +35 -0
- data/lib/ransack/nodes/condition.rb +168 -42
- data/lib/ransack/nodes/grouping.rb +8 -17
- data/lib/ransack/nodes/node.rb +23 -1
- data/lib/ransack/nodes/sort.rb +7 -4
- data/lib/ransack/nodes/value.rb +6 -0
- data/lib/ransack/predicate.rb +19 -6
- data/lib/ransack/search.rb +21 -10
- data/lib/ransack/translate.rb +43 -35
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack.rb +2 -1
- metadata +7 -6
|
@@ -99,7 +99,7 @@ module Ransack
|
|
|
99
99
|
self.groupings << grouping_object if grouping_object.values.any?
|
|
100
100
|
end
|
|
101
101
|
else
|
|
102
|
-
raise
|
|
102
|
+
raise InvalidSearchError,
|
|
103
103
|
"Invalid argument (#{groupings.class}) supplied to groupings="
|
|
104
104
|
end
|
|
105
105
|
end
|
|
@@ -107,7 +107,7 @@ module Ransack
|
|
|
107
107
|
|
|
108
108
|
def method_missing(method_id, *args)
|
|
109
109
|
method_name = method_id.to_s.dup
|
|
110
|
-
writer = method_name.sub!(
|
|
110
|
+
writer = method_name.sub!(/=\z/, ''.freeze)
|
|
111
111
|
if attribute_method?(method_name)
|
|
112
112
|
if writer
|
|
113
113
|
write_attribute(method_name, *args)
|
|
@@ -126,7 +126,7 @@ module Ransack
|
|
|
126
126
|
return true if @context.attribute_method?(stripped_name) ||
|
|
127
127
|
@context.attribute_method?(name)
|
|
128
128
|
case stripped_name
|
|
129
|
-
when
|
|
129
|
+
when /\A(g|c|m|groupings|conditions|combinator)=?\z/
|
|
130
130
|
true
|
|
131
131
|
else
|
|
132
132
|
stripped_name
|
|
@@ -147,9 +147,9 @@ module Ransack
|
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
def build(params)
|
|
150
|
-
params.
|
|
150
|
+
indifferent_params(params, 'grouping').each do |key, value|
|
|
151
151
|
case key
|
|
152
|
-
when
|
|
152
|
+
when /\A(g|c|m|groupings|conditions|combinator)\z/
|
|
153
153
|
self.send("#{key}=", value)
|
|
154
154
|
else
|
|
155
155
|
if @context.ransackable_scope?(key, @context.object)
|
|
@@ -214,25 +214,16 @@ module Ransack
|
|
|
214
214
|
# A condition is dropped when it fails validation, as an unknown
|
|
215
215
|
# attribute or predicate would be. One failure is worth naming: a
|
|
216
216
|
# single-value predicate given several values. A strict search raises
|
|
217
|
-
# for it, so the caller learns why the filter vanished (#1724).
|
|
218
|
-
# check only applies once the predicate and an attribute have resolved;
|
|
219
|
-
# a condition that is invalid for another reason keeps its behaviour.
|
|
217
|
+
# for it, so the caller learns why the filter vanished (#1724).
|
|
220
218
|
def add_condition(attrs)
|
|
221
219
|
condition = Condition.new(@context).build(attrs)
|
|
222
220
|
if condition.valid?
|
|
223
221
|
self.conditions << condition
|
|
224
|
-
elsif @context.strict_conditions? && arity_failure?
|
|
225
|
-
raise
|
|
226
|
-
"Predicate #{condition.predicate_name} takes a single value, " \
|
|
227
|
-
"#{condition.values.size} given for #{condition.attributes.map(&:name).join(', ')}"
|
|
222
|
+
elsif @context.strict_conditions? && condition.arity_failure?
|
|
223
|
+
raise condition.arity_error
|
|
228
224
|
end
|
|
229
225
|
end
|
|
230
226
|
|
|
231
|
-
def arity_failure?(condition)
|
|
232
|
-
condition.predicate && condition.attributes.any?(&:valid?) &&
|
|
233
|
-
!condition.valid_arity?
|
|
234
|
-
end
|
|
235
|
-
|
|
236
227
|
def remove_duplicate_conditions!
|
|
237
228
|
# If self.conditions.uniq! is called without passing a block, then
|
|
238
229
|
# conditions differing only by ransacker_args within attributes are
|
data/lib/ransack/nodes/node.rb
CHANGED
|
@@ -34,7 +34,7 @@ module Ransack
|
|
|
34
34
|
# this is the one place that normalises the spelling and, when the search
|
|
35
35
|
# is strict, rejects a value it does not recognise.
|
|
36
36
|
def combinator=(val)
|
|
37
|
-
normalised = val.to_s.downcase
|
|
37
|
+
normalised = scalar_param(val, 'combinator').to_s.downcase
|
|
38
38
|
@combinator = Constants::AND_OR.detect { |v| v == normalised }
|
|
39
39
|
|
|
40
40
|
if @combinator.nil? && !normalised.empty? && context&.strict_conditions?
|
|
@@ -42,6 +42,28 @@ module Ransack
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Search params usually come from the request, so a grouping, condition
|
|
48
|
+
# or sort given as something other than a hash (`q[g]=x`) is a malformed
|
|
49
|
+
# search, not a programming error, whether or not the search is strict.
|
|
50
|
+
def indifferent_params(params, node_name)
|
|
51
|
+
return params.with_indifferent_access if params.respond_to?(:with_indifferent_access)
|
|
52
|
+
|
|
53
|
+
raise InvalidSearchError,
|
|
54
|
+
"Invalid argument (#{params.class}) supplied for a #{node_name}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# A name, predicate, direction or combinator is a single value. Given an
|
|
58
|
+
# array or a hash (`q[s][0][dir][]=desc`), it used to be stringified and
|
|
59
|
+
# then silently ignored or defaulted, so the search ran as something
|
|
60
|
+
# other than what was asked for.
|
|
61
|
+
def scalar_param(value, field)
|
|
62
|
+
return value unless value.is_a?(Enumerable) || value.respond_to?(:to_unsafe_h)
|
|
63
|
+
|
|
64
|
+
raise InvalidSearchError, "Invalid argument (#{value.class}) supplied for #{field}"
|
|
65
|
+
end
|
|
66
|
+
|
|
45
67
|
end
|
|
46
68
|
end
|
|
47
69
|
end
|
data/lib/ransack/nodes/sort.rb
CHANGED
|
@@ -15,11 +15,14 @@ module Ransack
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def build(params)
|
|
18
|
-
params.
|
|
19
|
-
if key.match(
|
|
18
|
+
indifferent_params(params, 'sort').each do |key, value|
|
|
19
|
+
if key.match(/\A(name|dir|ransacker_args)\z/)
|
|
20
20
|
self.send("#{key}=", value)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
+
# A sort given without a direction is ascending, as it is from a
|
|
24
|
+
# string (`s: 'name'`).
|
|
25
|
+
self.dir = nil unless defined?(@dir)
|
|
23
26
|
|
|
24
27
|
self
|
|
25
28
|
end
|
|
@@ -30,12 +33,12 @@ module Ransack
|
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
def name=(name)
|
|
33
|
-
@name = context.resolve_aliases(name.to_s)
|
|
36
|
+
@name = context.resolve_aliases(scalar_param(name, 'a sort name').to_s)
|
|
34
37
|
context.bind(self, @name)
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
def dir=(dir)
|
|
38
|
-
dir = dir.downcase
|
|
41
|
+
dir = scalar_param(dir, 'a sort direction').to_s.downcase
|
|
39
42
|
@dir =
|
|
40
43
|
if dir == 'asc'.freeze || dir == 'desc'.freeze
|
|
41
44
|
dir
|
data/lib/ransack/nodes/value.rb
CHANGED
|
@@ -4,6 +4,12 @@ module Ransack
|
|
|
4
4
|
attr_accessor :value
|
|
5
5
|
delegate :present?, :blank?, to: :value
|
|
6
6
|
|
|
7
|
+
# The types whose cast builds one value from an Array: a multiparameter
|
|
8
|
+
# date or time (`created_at(1i)`, `created_at(2i)`, ...) arrives as one.
|
|
9
|
+
ARRAY_CAST_TYPES = %i[
|
|
10
|
+
date datetime timestamp time timestamptz datetimeoffset
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
7
13
|
def initialize(context, value = nil)
|
|
8
14
|
super(context)
|
|
9
15
|
@value = value
|
data/lib/ransack/predicate.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Ransack
|
|
2
2
|
class Predicate
|
|
3
|
-
attr_reader :name, :arel_predicate, :
|
|
4
|
-
:compound, :wants_array, :case_insensitive
|
|
3
|
+
attr_reader :name, :arel_predicate, :arel_node, :type, :formatter,
|
|
4
|
+
:validator, :compound, :wants_array, :case_insensitive
|
|
5
5
|
|
|
6
6
|
# Consulted at search time rather than captured at predicate-definition
|
|
7
7
|
# time, so that `Ransack.options[:ignore_blank_values]` set in an
|
|
@@ -28,14 +28,26 @@ module Ransack
|
|
|
28
28
|
detect_from_string str, chomp: true
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
# The longest registered predicate the key ends with, as `_<name>`.
|
|
32
|
+
# Only the tail a predicate name can fill is looked at, and each
|
|
33
|
+
# underscore there is one hash lookup, so the cost depends on neither
|
|
34
|
+
# the length of the key nor the number of predicates. The first
|
|
35
|
+
# underscore found gives the longest candidate, which is the one the
|
|
36
|
+
# longest-first scan this replaces would have picked.
|
|
31
37
|
def detect_from_string(str, chomp: false)
|
|
32
38
|
return unless str
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
str = str.to_s unless chomp
|
|
41
|
+
predicates = Ransack.predicates
|
|
42
|
+
from = str.length - predicates.max_name_length - 1
|
|
43
|
+
underscore = str.index(Constants::UNDERSCORE, from.negative? ? 0 : from)
|
|
44
|
+
while underscore
|
|
45
|
+
name = str[(underscore + 1)..]
|
|
46
|
+
if predicates.has_key?(name)
|
|
47
|
+
str.slice!(underscore..) if chomp
|
|
48
|
+
return name
|
|
38
49
|
end
|
|
50
|
+
underscore = str.index(Constants::UNDERSCORE, underscore + 1)
|
|
39
51
|
end
|
|
40
52
|
|
|
41
53
|
nil
|
|
@@ -46,6 +58,7 @@ module Ransack
|
|
|
46
58
|
def initialize(opts = {})
|
|
47
59
|
@name = opts[:name]
|
|
48
60
|
@arel_predicate = opts[:arel_predicate]
|
|
61
|
+
@arel_node = opts[:arel_node]
|
|
49
62
|
@type = opts[:type]
|
|
50
63
|
@formatter = opts[:formatter]
|
|
51
64
|
@validator = opts[:validator] || DEFAULT_VALIDATOR
|
data/lib/ransack/search.rb
CHANGED
|
@@ -7,7 +7,7 @@ require 'ransack/nodes/sort'
|
|
|
7
7
|
require 'ransack/nodes/grouping'
|
|
8
8
|
require 'ransack/context'
|
|
9
9
|
require 'ransack/naming'
|
|
10
|
-
require 'ransack/
|
|
10
|
+
require 'ransack/errors'
|
|
11
11
|
|
|
12
12
|
module Ransack
|
|
13
13
|
class Search
|
|
@@ -57,14 +57,23 @@ module Ransack
|
|
|
57
57
|
@context.evaluate(self, opts)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
GROUPING_KEYS = %w[g c m groupings conditions combinator].to_set.freeze
|
|
61
|
+
private_constant :GROUPING_KEYS
|
|
62
|
+
|
|
60
63
|
def build(params)
|
|
61
64
|
collapse_multiparameter_attributes!(params).each do |key, value|
|
|
62
65
|
if ['s'.freeze, 'sorts'.freeze].freeze.include?(key)
|
|
63
66
|
send("#{key}=", value)
|
|
64
67
|
elsif @context.ransackable_scope?(key, @context.object)
|
|
65
68
|
add_scope(key, value)
|
|
66
|
-
elsif
|
|
69
|
+
elsif GROUPING_KEYS.include?(key)
|
|
67
70
|
base.send("#{key}=", value)
|
|
71
|
+
elsif base.attribute_method?(key)
|
|
72
|
+
# Straight to the writer: going through the grouping's
|
|
73
|
+
# method_missing would check the key a second time, and would
|
|
74
|
+
# send a key that happens to name one of its own writers
|
|
75
|
+
# (`i18n_words`) there instead of building a condition.
|
|
76
|
+
base.send(:write_attribute, key, value)
|
|
68
77
|
elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
|
|
69
78
|
raise InvalidSearchError, "Invalid search term #{key}"
|
|
70
79
|
end
|
|
@@ -79,11 +88,12 @@ module Ransack
|
|
|
79
88
|
case args
|
|
80
89
|
when Array
|
|
81
90
|
args.each do |sort|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
sort =
|
|
92
|
+
case sort
|
|
93
|
+
when Hash then Nodes::Sort.new(@context).build(sort)
|
|
94
|
+
when String, Symbol, nil then Nodes::Sort.extract(@context, sort.to_s)
|
|
95
|
+
else raise InvalidSearchError, "Invalid argument (#{sort.class}) supplied to sorts="
|
|
96
|
+
end
|
|
87
97
|
add_sort(sort) if sort
|
|
88
98
|
end
|
|
89
99
|
when Hash
|
|
@@ -118,9 +128,9 @@ module Ransack
|
|
|
118
128
|
# params hash is built (#1472).
|
|
119
129
|
def method_missing(method_id, *args)
|
|
120
130
|
method_name = method_id.to_s
|
|
121
|
-
getter_name = method_name.sub(
|
|
131
|
+
getter_name = method_name.sub(/=\z/, ''.freeze)
|
|
122
132
|
if @context.ransackable_scope?(getter_name, @context.object)
|
|
123
|
-
if method_name
|
|
133
|
+
if method_name.end_with?('=')
|
|
124
134
|
add_scope getter_name, args.size == 1 ? args.first : args
|
|
125
135
|
else
|
|
126
136
|
@scope_args[method_name]
|
|
@@ -137,7 +147,7 @@ module Ransack
|
|
|
137
147
|
# before calling. Mirror method_missing so a search_form_with field is
|
|
138
148
|
# pre-filled the same way a search_form_for one is.
|
|
139
149
|
def respond_to_missing?(method_id, include_private = false)
|
|
140
|
-
getter_name = method_id.to_s.sub(
|
|
150
|
+
getter_name = method_id.to_s.sub(/=\z/, ''.freeze)
|
|
141
151
|
base.attribute_method?(getter_name) ||
|
|
142
152
|
@context.ransackable_scope?(getter_name, @context.object) ||
|
|
143
153
|
super
|
|
@@ -202,6 +212,7 @@ module Ransack
|
|
|
202
212
|
real_attribute, position = k.split(/\(|\)/)
|
|
203
213
|
value = attrs.delete(k)
|
|
204
214
|
next if position.nil?
|
|
215
|
+
next if value.is_a?(Array) || value.is_a?(Hash)
|
|
205
216
|
|
|
206
217
|
cast = Constants::A_S_I.include?(position.last) ? position.last : nil
|
|
207
218
|
position = position.to_i - 1
|
data/lib/ransack/translate.rb
CHANGED
|
@@ -72,80 +72,88 @@ module Ransack
|
|
|
72
72
|
|
|
73
73
|
private
|
|
74
74
|
|
|
75
|
+
# The module is shared by every thread, so nothing here is kept between
|
|
76
|
+
# calls: each helper is handed what it needs. Storing the name being
|
|
77
|
+
# translated on the module let one request read another's while both
|
|
78
|
+
# rendered sort links.
|
|
79
|
+
AttributeName = Struct.new(:context, :name, :attr_name, :assoc_path,
|
|
80
|
+
:associated_class, :include_associated)
|
|
81
|
+
private_constant :AttributeName
|
|
82
|
+
|
|
75
83
|
def attribute_name(context, name, include_associations = nil)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
assoc_path = context.association_path(name)
|
|
85
|
+
associated_class = context.traverse(assoc_path) if assoc_path.present?
|
|
86
|
+
part = AttributeName.new(
|
|
87
|
+
context, name, name.sub(/\A#{Regexp.escape(assoc_path)}_/, ''.freeze),
|
|
88
|
+
assoc_path, associated_class, include_associations && associated_class
|
|
89
|
+
)
|
|
81
90
|
|
|
82
|
-
defaults = default_attribute_name << fallback_args
|
|
91
|
+
defaults = default_attribute_name(part) << fallback_args(part)
|
|
83
92
|
options = { count: 1, default: defaults }
|
|
84
|
-
interpolations = build_interpolations(
|
|
93
|
+
interpolations = build_interpolations(part)
|
|
85
94
|
|
|
86
95
|
I18n.translate(defaults.shift, **options.merge(interpolations))
|
|
87
96
|
end
|
|
88
97
|
|
|
89
|
-
def default_attribute_name
|
|
90
|
-
["ransack.attributes.#{i18n_key(
|
|
98
|
+
def default_attribute_name(part)
|
|
99
|
+
["ransack.attributes.#{i18n_key(part.context.klass)}.#{part.name}".to_sym]
|
|
91
100
|
end
|
|
92
101
|
|
|
93
|
-
def fallback_args
|
|
94
|
-
if
|
|
102
|
+
def fallback_args(part)
|
|
103
|
+
if part.include_associated
|
|
95
104
|
'%{association_name} %{attr_fallback_name}'.freeze
|
|
96
105
|
else
|
|
97
106
|
'%{attr_fallback_name}'.freeze
|
|
98
107
|
end
|
|
99
108
|
end
|
|
100
109
|
|
|
101
|
-
def build_interpolations(
|
|
110
|
+
def build_interpolations(part)
|
|
102
111
|
{
|
|
103
|
-
attr_fallback_name: attr_fallback_name(
|
|
104
|
-
association_name: association_name
|
|
112
|
+
attr_fallback_name: attr_fallback_name(part),
|
|
113
|
+
association_name: association_name(part)
|
|
105
114
|
}.reject { |_, value| value.nil? }
|
|
106
115
|
end
|
|
107
116
|
|
|
108
|
-
def attr_fallback_name(
|
|
117
|
+
def attr_fallback_name(part)
|
|
109
118
|
I18n.t(
|
|
110
|
-
:"ransack.attributes.#{fallback_class(
|
|
111
|
-
default: default_interpolation(
|
|
119
|
+
:"ransack.attributes.#{fallback_class(part)}.#{part.attr_name}",
|
|
120
|
+
default: default_interpolation(part)
|
|
112
121
|
)
|
|
113
122
|
end
|
|
114
123
|
|
|
115
|
-
def fallback_class(
|
|
116
|
-
i18n_key(associated_class ||
|
|
124
|
+
def fallback_class(part)
|
|
125
|
+
i18n_key(part.associated_class || part.context.klass)
|
|
117
126
|
end
|
|
118
127
|
|
|
119
|
-
def association_name
|
|
120
|
-
association(
|
|
128
|
+
def association_name(part)
|
|
129
|
+
association(part.assoc_path, context: part.context) if part.include_associated
|
|
121
130
|
end
|
|
122
131
|
|
|
123
|
-
def default_interpolation(
|
|
132
|
+
def default_interpolation(part)
|
|
124
133
|
[
|
|
125
|
-
associated_attribute(
|
|
126
|
-
".attributes.#{
|
|
127
|
-
|
|
134
|
+
associated_attribute(part),
|
|
135
|
+
".attributes.#{part.attr_name}".to_sym,
|
|
136
|
+
part.attr_name.humanize
|
|
128
137
|
].flatten
|
|
129
138
|
end
|
|
130
139
|
|
|
131
|
-
def associated_attribute(
|
|
132
|
-
if associated_class
|
|
133
|
-
translated_attribute(associated_class)
|
|
140
|
+
def associated_attribute(part)
|
|
141
|
+
if part.associated_class
|
|
142
|
+
translated_attribute(part.associated_class, part.attr_name)
|
|
134
143
|
else
|
|
135
|
-
translated_ancestor_attributes
|
|
144
|
+
translated_ancestor_attributes(part)
|
|
136
145
|
end
|
|
137
146
|
end
|
|
138
147
|
|
|
139
|
-
def translated_attribute(
|
|
140
|
-
key = "#{
|
|
141
|
-
i18n_key(associated_class)}.#{@attr_name}"
|
|
148
|
+
def translated_attribute(klass, attr_name)
|
|
149
|
+
key = "#{klass.i18n_scope}.attributes.#{i18n_key(klass)}.#{attr_name}"
|
|
142
150
|
["#{key}.one".to_sym, key.to_sym]
|
|
143
151
|
end
|
|
144
152
|
|
|
145
|
-
def translated_ancestor_attributes
|
|
146
|
-
|
|
153
|
+
def translated_ancestor_attributes(part)
|
|
154
|
+
part.context.klass.ancestors
|
|
147
155
|
.select { |ancestor| ancestor.respond_to?(:model_name) }
|
|
148
|
-
.map { |ancestor| translated_attribute(ancestor) }
|
|
156
|
+
.map { |ancestor| translated_attribute(ancestor, part.attr_name) }
|
|
149
157
|
end
|
|
150
158
|
|
|
151
159
|
def i18n_key(klass)
|
data/lib/ransack/version.rb
CHANGED
data/lib/ransack.rb
CHANGED
|
@@ -2,12 +2,13 @@ require 'active_support/dependencies/autoload'
|
|
|
2
2
|
require 'active_support/deprecation'
|
|
3
3
|
require 'active_support/deprecator'
|
|
4
4
|
|
|
5
|
+
require 'active_support'
|
|
5
6
|
require 'active_support/core_ext'
|
|
7
|
+
require 'ransack/errors'
|
|
6
8
|
require 'ransack/configuration'
|
|
7
9
|
|
|
8
10
|
module Ransack
|
|
9
11
|
extend Configuration
|
|
10
|
-
class UntraversableAssociationError < StandardError; end
|
|
11
12
|
|
|
12
13
|
def self.deprecator
|
|
13
14
|
@deprecator ||= ActiveSupport::Deprecation.new('7.0', 'Ransack')
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ransack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0
|
|
4
|
+
version: 6.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ernie Miller
|
|
@@ -19,28 +19,28 @@ dependencies:
|
|
|
19
19
|
requirements:
|
|
20
20
|
- - ">="
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
22
|
+
version: '8.1'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
29
|
+
version: '8.1'
|
|
30
30
|
- !ruby/object:Gem::Dependency
|
|
31
31
|
name: activesupport
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
|
33
33
|
requirements:
|
|
34
34
|
- - ">="
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: '
|
|
36
|
+
version: '8.1'
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
40
|
requirements:
|
|
41
41
|
- - ">="
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: '
|
|
43
|
+
version: '8.1'
|
|
44
44
|
- !ruby/object:Gem::Dependency
|
|
45
45
|
name: i18n
|
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -82,6 +82,7 @@ files:
|
|
|
82
82
|
- lib/ransack/configuration.rb
|
|
83
83
|
- lib/ransack/constants.rb
|
|
84
84
|
- lib/ransack/context.rb
|
|
85
|
+
- lib/ransack/errors.rb
|
|
85
86
|
- lib/ransack/helpers.rb
|
|
86
87
|
- lib/ransack/helpers/form_builder.rb
|
|
87
88
|
- lib/ransack/helpers/form_helper.rb
|
|
@@ -140,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
140
141
|
requirements:
|
|
141
142
|
- - ">="
|
|
142
143
|
- !ruby/object:Gem::Version
|
|
143
|
-
version: '3.
|
|
144
|
+
version: '3.3'
|
|
144
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
146
|
requirements:
|
|
146
147
|
- - ">="
|