ransack 2.3.2 → 2.5.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/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/cronjob.yml +102 -0
- data/.github/workflows/rubocop.yml +20 -0
- data/.github/workflows/test.yml +163 -0
- data/.rubocop.yml +44 -0
- data/CHANGELOG.md +28 -1
- data/CONTRIBUTING.md +16 -11
- data/Gemfile +5 -3
- data/README.md +167 -30
- data/bug_report_templates/test-ransack-scope-and-column-same-name.rb +78 -0
- data/bug_report_templates/test-ransacker-arel-present-predicate.rb +71 -0
- data/docs/img/create_release.png +0 -0
- data/docs/release_process.md +17 -0
- data/{polyamorous/lib → lib}/polyamorous/activerecord_5.2_ruby_2/join_association.rb +4 -0
- data/{polyamorous/lib → lib}/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +0 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
- data/{polyamorous/lib → lib}/polyamorous/activerecord_6.0_ruby_2/join_association.rb +0 -1
- data/{polyamorous/lib → lib}/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +0 -1
- data/{polyamorous/lib → lib}/polyamorous/activerecord_6.0_ruby_2/reflection.rb +0 -1
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
- data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
- data/{polyamorous/lib → lib}/polyamorous/activerecord_6.1_ruby_2/reflection.rb +0 -1
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/join_dependency.rb +1 -0
- data/lib/polyamorous/activerecord_7.0_ruby_2/reflection.rb +1 -0
- data/{polyamorous/lib → lib}/polyamorous/join.rb +0 -0
- data/{polyamorous/lib → lib/polyamorous}/polyamorous.rb +1 -1
- data/{polyamorous/lib → lib}/polyamorous/swapping_reflection_class.rb +0 -0
- data/{polyamorous/lib → lib}/polyamorous/tree_node.rb +0 -0
- data/lib/polyamorous.rb +1 -0
- data/lib/ransack/adapters/active_record/base.rb +5 -1
- data/lib/ransack/adapters/active_record/context.rb +55 -13
- data/lib/ransack/adapters/active_record/ransack/constants.rb +1 -1
- data/lib/ransack/adapters/active_record/ransack/context.rb +1 -0
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +11 -3
- data/lib/ransack/configuration.rb +31 -1
- data/lib/ransack/constants.rb +2 -2
- data/lib/ransack/helpers/form_builder.rb +3 -3
- data/lib/ransack/helpers.rb +1 -1
- data/lib/ransack/locale/sv.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +1 -1
- data/lib/ransack/nodes/condition.rb +0 -2
- data/lib/ransack/nodes/grouping.rb +1 -1
- data/lib/ransack/nodes/sort.rb +3 -3
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/search.rb +4 -1
- data/lib/ransack/translate.rb +4 -4
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack.rb +2 -2
- data/ransack.gemspec +8 -14
- data/spec/blueprints/articles.rb +1 -1
- data/spec/blueprints/comments.rb +1 -1
- data/spec/blueprints/notes.rb +1 -1
- data/spec/blueprints/tags.rb +1 -1
- data/spec/console.rb +5 -5
- data/spec/helpers/ransack_helper.rb +1 -1
- data/spec/{ransack → polyamorous}/join_association_spec.rb +8 -1
- data/spec/{ransack → polyamorous}/join_dependency_spec.rb +0 -0
- data/spec/{ransack → polyamorous}/join_spec.rb +0 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +26 -15
- data/spec/ransack/adapters/active_record/context_spec.rb +19 -18
- data/spec/ransack/configuration_spec.rb +24 -0
- data/spec/ransack/helpers/form_helper_spec.rb +16 -16
- data/spec/ransack/nodes/condition_spec.rb +13 -0
- data/spec/ransack/nodes/grouping_spec.rb +2 -2
- data/spec/ransack/predicate_spec.rb +1 -1
- data/spec/ransack/search_spec.rb +215 -30
- data/spec/spec_helper.rb +7 -5
- data/spec/support/schema.rb +28 -2
- metadata +45 -47
- data/.travis.yml +0 -47
- data/polyamorous/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +0 -12
- data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +0 -2
- data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +0 -2
- data/polyamorous/lib/polyamorous/version.rb +0 -3
- data/polyamorous/polyamorous.gemspec +0 -27
@@ -18,6 +18,10 @@ module Ransack
|
|
18
18
|
Search.new(self, params, options)
|
19
19
|
end
|
20
20
|
|
21
|
+
def ransack!(params = {}, options = {})
|
22
|
+
ransack(params, options.merge(ignore_unknown_conditions: false))
|
23
|
+
end
|
24
|
+
|
21
25
|
def ransacker(name, opts = {}, &block)
|
22
26
|
self._ransackers = _ransackers.merge name.to_s => Ransacker
|
23
27
|
.new(self, name, opts, &block)
|
@@ -66,7 +70,7 @@ module Ransack
|
|
66
70
|
end
|
67
71
|
|
68
72
|
# ransack_scope_skip_sanitize_args, by default, returns an empty array.
|
69
|
-
# i.e. use the sanitize_scope_args setting to
|
73
|
+
# i.e. use the sanitize_scope_args setting to determine if args should be converted.
|
70
74
|
# For overriding with a list of scopes which should be passed the args as-is.
|
71
75
|
#
|
72
76
|
def ransackable_scopes_skip_sanitize_args
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'ransack/context'
|
2
|
-
require 'polyamorous'
|
2
|
+
require 'polyamorous/polyamorous'
|
3
3
|
|
4
4
|
module Ransack
|
5
5
|
module Adapters
|
@@ -42,6 +42,17 @@ module Ransack
|
|
42
42
|
if scope_or_sort.is_a?(Symbol)
|
43
43
|
relation = relation.send(scope_or_sort)
|
44
44
|
else
|
45
|
+
case Ransack.options[:postgres_fields_sort_option]
|
46
|
+
when :nulls_first
|
47
|
+
scope_or_sort = scope_or_sort.direction == :asc ? Arel.sql("#{scope_or_sort.to_sql} NULLS FIRST") : Arel.sql("#{scope_or_sort.to_sql} NULLS LAST")
|
48
|
+
when :nulls_last
|
49
|
+
scope_or_sort = scope_or_sort.direction == :asc ? Arel.sql("#{scope_or_sort.to_sql} NULLS LAST") : Arel.sql("#{scope_or_sort.to_sql} NULLS FIRST")
|
50
|
+
when :nulls_always_first
|
51
|
+
scope_or_sort = Arel.sql("#{scope_or_sort.to_sql} NULLS FIRST")
|
52
|
+
when :nulls_always_last
|
53
|
+
scope_or_sort = Arel.sql("#{scope_or_sort.to_sql} NULLS LAST")
|
54
|
+
end
|
55
|
+
|
45
56
|
relation = relation.order(scope_or_sort)
|
46
57
|
end
|
47
58
|
end
|
@@ -99,7 +110,9 @@ module Ransack
|
|
99
110
|
def join_sources
|
100
111
|
base, joins = begin
|
101
112
|
alias_tracker = ::ActiveRecord::Associations::AliasTracker.create(self.klass.connection, @object.table.name, [])
|
102
|
-
constraints = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::
|
113
|
+
constraints = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
|
114
|
+
@join_dependency.join_constraints(@object.joins_values, alias_tracker, @object.references_values)
|
115
|
+
elsif ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_0)
|
103
116
|
@join_dependency.join_constraints(@object.joins_values, alias_tracker)
|
104
117
|
else
|
105
118
|
@join_dependency.join_constraints(@object.joins_values, @join_type, alias_tracker)
|
@@ -172,16 +185,31 @@ module Ransack
|
|
172
185
|
private
|
173
186
|
|
174
187
|
def extract_correlated_key(join_root)
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
188
|
+
case join_root
|
189
|
+
when Arel::Nodes::OuterJoin
|
190
|
+
# one of join_root.right/join_root.left is expected to be Arel::Nodes::On
|
191
|
+
if join_root.right.is_a?(Arel::Nodes::On)
|
192
|
+
extract_correlated_key(join_root.right.expr)
|
193
|
+
elsif join_root.left.is_a?(Arel::Nodes::On)
|
194
|
+
extract_correlated_key(join_root.left.expr)
|
195
|
+
else
|
196
|
+
raise 'Ransack encountered an unexpected arel structure'
|
197
|
+
end
|
198
|
+
when Arel::Nodes::Equality
|
199
|
+
pk = primary_key
|
200
|
+
if join_root.left == pk
|
201
|
+
join_root.right
|
202
|
+
elsif join_root.right == pk
|
203
|
+
join_root.left
|
204
|
+
else
|
205
|
+
nil
|
206
|
+
end
|
207
|
+
when Arel::Nodes::And
|
208
|
+
extract_correlated_key(join_root.left) || extract_correlated_key(join_root.right)
|
183
209
|
else
|
184
|
-
|
210
|
+
# eg parent was Arel::Nodes::And and the evaluated side was one of
|
211
|
+
# Arel::Nodes::Grouping or MultiTenant::TenantEnforcementClause
|
212
|
+
nil
|
185
213
|
end
|
186
214
|
end
|
187
215
|
|
@@ -310,7 +338,11 @@ module Ransack
|
|
310
338
|
@join_dependency.instance_variable_get(:@join_root).children.push found_association
|
311
339
|
|
312
340
|
# Builds the arel nodes properly for this association
|
313
|
-
|
341
|
+
if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
|
342
|
+
@tables_pot[found_association] = @join_dependency.construct_tables_for_association!(jd.instance_variable_get(:@join_root), found_association)
|
343
|
+
else
|
344
|
+
@join_dependency.send(:construct_tables!, jd.instance_variable_get(:@join_root))
|
345
|
+
end
|
314
346
|
|
315
347
|
# Leverage the stashed association functionality in AR
|
316
348
|
@object = @object.joins(jd)
|
@@ -320,12 +352,22 @@ module Ransack
|
|
320
352
|
def extract_joins(association)
|
321
353
|
parent = @join_dependency.instance_variable_get(:@join_root)
|
322
354
|
reflection = association.reflection
|
323
|
-
join_constraints =
|
355
|
+
join_constraints = if ::Gem::Version.new(::ActiveRecord::VERSION::STRING) >= ::Gem::Version.new(Constants::RAILS_6_1)
|
356
|
+
association.join_constraints_with_tables(
|
357
|
+
parent.table,
|
358
|
+
parent.base_klass,
|
359
|
+
Arel::Nodes::OuterJoin,
|
360
|
+
@join_dependency.instance_variable_get(:@alias_tracker),
|
361
|
+
@tables_pot[association]
|
362
|
+
)
|
363
|
+
else
|
364
|
+
association.join_constraints(
|
324
365
|
parent.table,
|
325
366
|
parent.base_klass,
|
326
367
|
Arel::Nodes::OuterJoin,
|
327
368
|
@join_dependency.instance_variable_get(:@alias_tracker)
|
328
369
|
)
|
370
|
+
end
|
329
371
|
join_constraints.to_a.flatten
|
330
372
|
end
|
331
373
|
end
|
@@ -97,7 +97,7 @@ module Ransack
|
|
97
97
|
arel_predicate: proc { |v| v ? EQ : NOT_EQ },
|
98
98
|
compounds: false,
|
99
99
|
type: :boolean,
|
100
|
-
validator: proc { |v| BOOLEAN_VALUES.include?(v)},
|
100
|
+
validator: proc { |v| BOOLEAN_VALUES.include?(v) },
|
101
101
|
formatter: proc { |v| nil }
|
102
102
|
}
|
103
103
|
],
|
@@ -28,6 +28,7 @@ module Ransack
|
|
28
28
|
@join_type = options[:join_type] || Polyamorous::OuterJoin
|
29
29
|
@search_key = options[:search_key] || Ransack.options[:search_key]
|
30
30
|
@associations_pot = {}
|
31
|
+
@tables_pot = {}
|
31
32
|
@lock_associations = []
|
32
33
|
|
33
34
|
@base = @join_dependency.instance_variable_get(:@join_root)
|
@@ -47,12 +47,20 @@ module Ransack
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def casted_array?(predicate)
|
50
|
-
predicate.
|
50
|
+
value_from(predicate).is_a?(Array) && predicate.is_a?(Arel::Nodes::Casted)
|
51
|
+
end
|
52
|
+
|
53
|
+
def value_from(predicate)
|
54
|
+
if predicate.respond_to?(:value)
|
55
|
+
predicate.value # Rails 6.1
|
56
|
+
elsif predicate.respond_to?(:val)
|
57
|
+
predicate.val # Rails 5.2, 6.0
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
61
|
def format_values_for(predicate)
|
54
|
-
predicate.
|
55
|
-
|
62
|
+
value_from(predicate).map do |val|
|
63
|
+
val.is_a?(String) ? Arel::Nodes.build_quoted(val) : val
|
56
64
|
end
|
57
65
|
end
|
58
66
|
|
@@ -33,7 +33,9 @@ module Ransack
|
|
33
33
|
:up_arrow => '▼'.freeze,
|
34
34
|
:down_arrow => '▲'.freeze,
|
35
35
|
:default_arrow => nil,
|
36
|
-
:sanitize_scope_args => true
|
36
|
+
:sanitize_scope_args => true,
|
37
|
+
:postgres_fields_sort_option => nil,
|
38
|
+
:strip_whitespace => true
|
37
39
|
}
|
38
40
|
|
39
41
|
def configure
|
@@ -141,6 +143,21 @@ module Ransack
|
|
141
143
|
self.options[:sanitize_scope_args] = boolean
|
142
144
|
end
|
143
145
|
|
146
|
+
# The `NULLS FIRST` and `NULLS LAST` options can be used to determine
|
147
|
+
# whether nulls appear before or after non-null values in the sort ordering.
|
148
|
+
#
|
149
|
+
# User may want to configure it like this:
|
150
|
+
#
|
151
|
+
# Ransack.configure do |c|
|
152
|
+
# c.postgres_fields_sort_option = :nulls_first # or e.g. :nulls_always_last
|
153
|
+
# end
|
154
|
+
#
|
155
|
+
# See this feature: https://www.postgresql.org/docs/13/queries-order.html
|
156
|
+
#
|
157
|
+
def postgres_fields_sort_option=(setting)
|
158
|
+
self.options[:postgres_fields_sort_option] = setting
|
159
|
+
end
|
160
|
+
|
144
161
|
# By default, Ransack displays sort order indicator arrows in sort links.
|
145
162
|
# The default may be globally overridden in an initializer file like
|
146
163
|
# `config/initializers/ransack.rb` as follows:
|
@@ -154,6 +171,19 @@ module Ransack
|
|
154
171
|
self.options[:hide_sort_order_indicators] = boolean
|
155
172
|
end
|
156
173
|
|
174
|
+
# By default, Ransack displays strips all whitespace when searching for a string.
|
175
|
+
# The default may be globally changed in an initializer file like
|
176
|
+
# `config/initializers/ransack.rb` as follows:
|
177
|
+
#
|
178
|
+
# Ransack.configure do |config|
|
179
|
+
# # Enable whitespace stripping for string searches
|
180
|
+
# config.strip_whitespace = true
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
def strip_whitespace=(boolean)
|
184
|
+
self.options[:strip_whitespace] = boolean
|
185
|
+
end
|
186
|
+
|
157
187
|
def arel_predicate_with_suffix(arel_predicate, suffix)
|
158
188
|
if arel_predicate === Proc
|
159
189
|
proc { |v| "#{arel_predicate.call(v)}#{suffix}" }
|
data/lib/ransack/constants.rb
CHANGED
@@ -36,7 +36,7 @@ module Ransack
|
|
36
36
|
'lt'.freeze, 'lteq'.freeze,
|
37
37
|
'gt'.freeze, 'gteq'.freeze,
|
38
38
|
'in'.freeze, 'not_in'.freeze
|
39
|
-
|
39
|
+
].freeze
|
40
40
|
A_S_I = ['a'.freeze, 's'.freeze, 'i'.freeze].freeze
|
41
41
|
|
42
42
|
EQ = 'eq'.freeze
|
@@ -46,9 +46,9 @@ module Ransack
|
|
46
46
|
CONT = 'cont'.freeze
|
47
47
|
|
48
48
|
RAILS_6_0 = '6.0.0'.freeze
|
49
|
+
RAILS_6_1 = '6.1.0'.freeze
|
49
50
|
|
50
51
|
RANSACK_SLASH_SEARCHES = 'ransack/searches'.freeze
|
51
52
|
RANSACK_SLASH_SEARCHES_SLASH_SEARCH = 'ransack/searches/search'.freeze
|
52
53
|
end
|
53
54
|
end
|
54
|
-
|
@@ -45,9 +45,9 @@ module Ransack
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def attribute_select(options = nil, html_options = nil, action = nil)
|
48
|
-
options
|
49
|
-
html_options
|
50
|
-
action
|
48
|
+
options ||= {}
|
49
|
+
html_options ||= {}
|
50
|
+
action ||= Constants::SEARCH
|
51
51
|
default = options.delete(:default)
|
52
52
|
raise ArgumentError, formbuilder_error_message(
|
53
53
|
"#{action}_select") unless object.respond_to?(:context)
|
data/lib/ransack/helpers.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'ransack/helpers/form_builder'
|
2
|
-
require 'ransack/helpers/form_helper'
|
2
|
+
require 'ransack/helpers/form_helper'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
sv:
|
2
|
+
ransack:
|
3
|
+
search: "sök"
|
4
|
+
predicate: "predikat"
|
5
|
+
and: "och"
|
6
|
+
or: "eller"
|
7
|
+
any: "vilken som"
|
8
|
+
all: "alla"
|
9
|
+
combinator: "kombinator"
|
10
|
+
attribute: "attribut"
|
11
|
+
value: "värde"
|
12
|
+
condition: "villkor"
|
13
|
+
sort: "sortera"
|
14
|
+
asc: "stigande"
|
15
|
+
desc: "fallande"
|
16
|
+
predicates:
|
17
|
+
eq: "lika med"
|
18
|
+
eq_any: "lika med vilket som"
|
19
|
+
eq_all: "lika med alla"
|
20
|
+
not_eq: "inte lika med"
|
21
|
+
not_eq_any: "inte lika med någon"
|
22
|
+
not_eq_all: "inte lika med alla"
|
23
|
+
matches: "matchar"
|
24
|
+
matches_any: "matchar någon"
|
25
|
+
matches_all: "matchar alla"
|
26
|
+
does_not_match: "matchar inte"
|
27
|
+
does_not_match_any: "matchar inte någon"
|
28
|
+
does_not_match_all: "matchar inte alla"
|
29
|
+
lt: "mindre än"
|
30
|
+
lt_any: "mindre än någon"
|
31
|
+
lt_all: "mindre än alla"
|
32
|
+
lteq: "mindre än eller lika med"
|
33
|
+
lteq_any: "mindre än eller lika med någon"
|
34
|
+
lteq_all: "mindre än eller lika med alla"
|
35
|
+
gt: "större än"
|
36
|
+
gt_any: "större än någon"
|
37
|
+
gt_all: "större än alla"
|
38
|
+
gteq: "större än eller lika med"
|
39
|
+
gteq_any: "större än eller lika med någon"
|
40
|
+
gteq_all: "större än eller lika med alla"
|
41
|
+
in: "i"
|
42
|
+
in_any: "i någon"
|
43
|
+
in_all: "i alla"
|
44
|
+
not_in: "inte i"
|
45
|
+
not_in_any: "inte i någon"
|
46
|
+
not_in_all: "inte i alla"
|
47
|
+
cont: "innehåller"
|
48
|
+
cont_any: "innehåller någon"
|
49
|
+
cont_all: "innehåller alla"
|
50
|
+
not_cont: "innehåller inte"
|
51
|
+
not_cont_any: "innehåller inte någon"
|
52
|
+
not_cont_all: "innehåller inte alla"
|
53
|
+
start: "börjar med"
|
54
|
+
start_any: "börjar med någon"
|
55
|
+
start_all: "börjar med alla"
|
56
|
+
not_start: "börjar inte med"
|
57
|
+
not_start_any: "börjar inte med någon"
|
58
|
+
not_start_all: "börjar inte med alla"
|
59
|
+
end: "slutar med"
|
60
|
+
end_any: "slutar med någon"
|
61
|
+
end_all: "slutar med alla"
|
62
|
+
not_end: "slutar inte med"
|
63
|
+
not_end_any: "slutar inte med någon"
|
64
|
+
not_end_all: "slutar inte med alla"
|
65
|
+
'true': "är sant"
|
66
|
+
'false': "är falskt"
|
67
|
+
present: "existerar"
|
68
|
+
blank: "är tom"
|
69
|
+
'null': "är null"
|
70
|
+
not_null: "är inte null"
|
@@ -127,7 +127,6 @@ module Ransack
|
|
127
127
|
alias :m= :combinator=
|
128
128
|
alias :m :combinator
|
129
129
|
|
130
|
-
|
131
130
|
# == build_attribute
|
132
131
|
#
|
133
132
|
# This method was originally called from Nodes::Grouping#new_condition
|
@@ -263,7 +262,6 @@ module Ransack
|
|
263
262
|
attr.attr
|
264
263
|
end
|
265
264
|
|
266
|
-
|
267
265
|
def default_type
|
268
266
|
predicate.type || (attributes.first && attributes.first.type)
|
269
267
|
end
|
@@ -108,7 +108,7 @@ module Ransack
|
|
108
108
|
alias :g= :groupings=
|
109
109
|
|
110
110
|
def method_missing(method_id, *args)
|
111
|
-
method_name = method_id.to_s
|
111
|
+
method_name = method_id.to_s.dup
|
112
112
|
writer = method_name.sub!(/\=$/, ''.freeze)
|
113
113
|
if attribute_method?(method_name)
|
114
114
|
if writer
|
data/lib/ransack/nodes/sort.rb
CHANGED
@@ -9,7 +9,7 @@ module Ransack
|
|
9
9
|
class << self
|
10
10
|
def extract(context, str)
|
11
11
|
return unless str
|
12
|
-
attr, direction = str.split(/\s+/,2)
|
12
|
+
attr, direction = str.split(/\s+/, 2)
|
13
13
|
self.new(context).build(name: attr, dir: direction)
|
14
14
|
end
|
15
15
|
end
|
@@ -31,8 +31,8 @@ module Ransack
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def name=(name)
|
34
|
-
@name = name
|
35
|
-
context.bind(self, name)
|
34
|
+
@name = context.ransackable_alias(name) || name
|
35
|
+
context.bind(self, @name)
|
36
36
|
end
|
37
37
|
|
38
38
|
def dir=(dir)
|
data/lib/ransack/nodes/value.rb
CHANGED
data/lib/ransack/search.rb
CHANGED
@@ -15,9 +15,11 @@ module Ransack
|
|
15
15
|
:translate, :to => :base
|
16
16
|
|
17
17
|
def initialize(object, params = {}, options = {})
|
18
|
+
strip_whitespace = options.fetch(:strip_whitespace, Ransack.options[:strip_whitespace])
|
18
19
|
params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
|
19
20
|
if params.is_a? Hash
|
20
21
|
params = params.dup
|
22
|
+
params = params.transform_values { |v| v.is_a?(String) && strip_whitespace ? v.strip : v }
|
21
23
|
params.delete_if { |k, v| [*v].all?{ |i| i.blank? && i != false } }
|
22
24
|
else
|
23
25
|
params = {}
|
@@ -29,6 +31,7 @@ module Ransack
|
|
29
31
|
)
|
30
32
|
@scope_args = {}
|
31
33
|
@sorts ||= []
|
34
|
+
@ignore_unknown_conditions = options[:ignore_unknown_conditions] == false ? false : true
|
32
35
|
build(params.with_indifferent_access)
|
33
36
|
end
|
34
37
|
|
@@ -44,7 +47,7 @@ module Ransack
|
|
44
47
|
base.send("#{key}=", value)
|
45
48
|
elsif @context.ransackable_scope?(key, @context.object)
|
46
49
|
add_scope(key, value)
|
47
|
-
elsif !Ransack.options[:ignore_unknown_conditions]
|
50
|
+
elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
|
48
51
|
raise ArgumentError, "Invalid search term #{key}"
|
49
52
|
end
|
50
53
|
end
|
data/lib/ransack/translate.rb
CHANGED
@@ -32,6 +32,7 @@ module Ransack
|
|
32
32
|
defaults = base_ancestors.map do |klass|
|
33
33
|
"ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
|
34
34
|
end
|
35
|
+
defaults << options.delete(:default) if options[:default]
|
35
36
|
|
36
37
|
translated_names = attribute_names.map do |name|
|
37
38
|
attribute_name(context, name, options[:include_associations])
|
@@ -48,9 +49,8 @@ module Ransack
|
|
48
49
|
defaults << "%{attributes}".freeze
|
49
50
|
end
|
50
51
|
|
51
|
-
defaults << options.delete(:default) if options[:default]
|
52
52
|
options.reverse_merge! count: 1, default: defaults
|
53
|
-
I18n.translate(defaults.shift, options.merge(interpolations))
|
53
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
54
54
|
end
|
55
55
|
|
56
56
|
def association(key, options = {})
|
@@ -67,7 +67,7 @@ module Ransack
|
|
67
67
|
end
|
68
68
|
defaults << context.traverse(key).model_name.human
|
69
69
|
options = { :count => 1, :default => defaults }
|
70
|
-
I18n.translate(defaults.shift, options)
|
70
|
+
I18n.translate(defaults.shift, **options)
|
71
71
|
end
|
72
72
|
|
73
73
|
private
|
@@ -83,7 +83,7 @@ module Ransack
|
|
83
83
|
options = { count: 1, default: defaults }
|
84
84
|
interpolations = build_interpolations(associated_class)
|
85
85
|
|
86
|
-
I18n.translate(defaults.shift, options.merge(interpolations))
|
86
|
+
I18n.translate(defaults.shift, **options.merge(interpolations))
|
87
87
|
end
|
88
88
|
|
89
89
|
def default_attribute_name
|
data/lib/ransack/version.rb
CHANGED
data/lib/ransack.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'active_support/core_ext'
|
2
2
|
require 'ransack/configuration'
|
3
3
|
require 'ransack/adapters'
|
4
|
-
require 'polyamorous'
|
4
|
+
require 'polyamorous/polyamorous'
|
5
5
|
|
6
6
|
Ransack::Adapters.object_mapper.require_constants
|
7
7
|
|
8
8
|
module Ransack
|
9
9
|
extend Configuration
|
10
|
-
class UntraversableAssociationError < StandardError; end
|
10
|
+
class UntraversableAssociationError < StandardError; end
|
11
11
|
end
|
12
12
|
|
13
13
|
Ransack.configure do |config|
|
data/ransack.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
2
3
|
$:.push File.expand_path("../lib", __FILE__)
|
3
4
|
require "ransack/version"
|
4
5
|
|
@@ -6,27 +7,20 @@ Gem::Specification.new do |s|
|
|
6
7
|
s.name = "ransack"
|
7
8
|
s.version = Ransack::VERSION
|
8
9
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack","Sean Carroll"]
|
10
|
-
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com","sfcarroll@gmail.com"]
|
10
|
+
s.authors = ["Ernie Miller", "Ryan Bigg", "Jon Atack", "Sean Carroll"]
|
11
|
+
s.email = ["ernie@erniemiller.org", "radarlistener@gmail.com", "jonnyatack@gmail.com", "sfcarroll@gmail.com"]
|
11
12
|
s.homepage = "https://github.com/activerecord-hackery/ransack"
|
12
13
|
s.summary = %q{Object-based searching for Active Record and Mongoid (currently).}
|
13
14
|
s.description = %q{Ransack is the successor to the MetaSearch gem. It improves and expands upon MetaSearch's functionality, but does not have a 100%-compatible API.}
|
14
|
-
s.required_ruby_version = '>= 2.
|
15
|
+
s.required_ruby_version = '>= 2.6'
|
15
16
|
s.license = 'MIT'
|
16
17
|
|
17
|
-
s.add_dependency 'activerecord', '>= 5.2.
|
18
|
-
s.add_dependency 'activesupport', '>= 5.2.
|
18
|
+
s.add_dependency 'activerecord', '>= 5.2.4'
|
19
|
+
s.add_dependency 'activesupport', '>= 5.2.4'
|
19
20
|
s.add_dependency 'i18n'
|
20
|
-
s.add_dependency 'polyamorous', Ransack::VERSION.to_s
|
21
21
|
|
22
22
|
s.files = `git ls-files`.split("\n")
|
23
|
-
|
24
|
-
s.
|
25
|
-
.split("\n")
|
26
|
-
|
27
|
-
s.executables = `git ls-files -- bin/*`
|
28
|
-
.split("\n")
|
29
|
-
.map { |f| File.basename(f) }
|
30
|
-
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
31
25
|
s.require_paths = ["lib"]
|
32
26
|
end
|
data/spec/blueprints/articles.rb
CHANGED
data/spec/blueprints/comments.rb
CHANGED
data/spec/blueprints/notes.rb
CHANGED
data/spec/blueprints/tags.rb
CHANGED
data/spec/console.rb
CHANGED
@@ -14,11 +14,11 @@ Sham.define do
|
|
14
14
|
title { Faker::Lorem.sentence }
|
15
15
|
body { Faker::Lorem.paragraph }
|
16
16
|
salary { |index| 30000 + (index * 1000) }
|
17
|
-
tag_name { Faker::Lorem.words(3).join(' ') }
|
18
|
-
note { Faker::Lorem.words(7).join(' ') }
|
19
|
-
only_admin { Faker::Lorem.words(3).join(' ') }
|
20
|
-
only_search { Faker::Lorem.words(3).join(' ') }
|
21
|
-
only_sort { Faker::Lorem.words(3).join(' ') }
|
17
|
+
tag_name { Faker::Lorem.words(number: 3).join(' ') }
|
18
|
+
note { Faker::Lorem.words(number: 7).join(' ') }
|
19
|
+
only_admin { Faker::Lorem.words(number: 3).join(' ') }
|
20
|
+
only_search { Faker::Lorem.words(number: 3).join(' ') }
|
21
|
+
only_sort { Faker::Lorem.words(number: 3).join(' ') }
|
22
22
|
notable_id { |id| id }
|
23
23
|
end
|
24
24
|
|
@@ -10,7 +10,14 @@ module Polyamorous
|
|
10
10
|
new_join_association(reflection, parent.children, Article)
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
subject { new_join_association(reflection, parent.children, Person) }
|
14
|
+
|
15
|
+
it 'respects polymorphism on equality test' do
|
16
|
+
expect(subject).to eq new_join_association(reflection, parent.children, Person)
|
17
|
+
expect(subject).not_to eq new_join_association(reflection, parent.children, Article)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'leaves the original reflection intact for thread safety' do
|
14
21
|
reflection.instance_variable_set(:@klass, Article)
|
15
22
|
join_association
|
16
23
|
.swapping_reflection_klass(reflection, Person) do |new_reflection|
|
File without changes
|
File without changes
|