ransack 1.7.0 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/FUNDING.yml +3 -0
- data/.github/SECURITY.md +12 -0
- data/.github/workflows/test.yml +120 -0
- data/.gitignore +3 -0
- data/CHANGELOG.md +463 -27
- data/CONTRIBUTING.md +52 -22
- data/Gemfile +24 -24
- data/README.md +453 -126
- data/Rakefile +6 -25
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
- data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
- data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
- 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/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
- data/lib/polyamorous/join.rb +70 -0
- data/lib/polyamorous/polyamorous.rb +24 -0
- data/lib/polyamorous/swapping_reflection_class.rb +11 -0
- data/lib/polyamorous/tree_node.rb +7 -0
- data/lib/ransack/adapters/active_record/base.rb +27 -2
- data/lib/ransack/adapters/active_record/context.rb +213 -139
- data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
- data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
- data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
- data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
- data/lib/ransack/adapters/active_record.rb +11 -10
- data/lib/ransack/adapters.rb +45 -23
- data/lib/ransack/configuration.rb +107 -4
- data/lib/ransack/constants.rb +13 -26
- data/lib/ransack/context.rb +45 -33
- data/lib/ransack/helpers/form_builder.rb +21 -12
- data/lib/ransack/helpers/form_helper.rb +75 -70
- data/lib/ransack/locale/ar.yml +70 -0
- data/lib/ransack/locale/az.yml +70 -0
- data/lib/ransack/locale/bg.yml +70 -0
- data/lib/ransack/locale/ca.yml +70 -0
- data/lib/ransack/locale/da.yml +70 -0
- data/lib/ransack/locale/el.yml +70 -0
- data/lib/ransack/locale/es.yml +22 -22
- data/lib/ransack/locale/fa.yml +70 -0
- data/lib/ransack/locale/fi.yml +71 -0
- data/lib/ransack/locale/id.yml +70 -0
- data/lib/ransack/locale/it.yml +70 -0
- data/lib/ransack/locale/ja.yml +70 -0
- data/lib/ransack/locale/nl.yml +4 -4
- data/lib/ransack/locale/pt-BR.yml +70 -0
- data/lib/ransack/locale/ru.yml +70 -0
- data/lib/ransack/locale/sk.yml +70 -0
- data/lib/ransack/locale/tr.yml +70 -0
- data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
- data/lib/ransack/locale/zh-TW.yml +70 -0
- data/lib/ransack/nodes/attribute.rb +5 -2
- data/lib/ransack/nodes/bindable.rb +18 -6
- data/lib/ransack/nodes/condition.rb +85 -28
- data/lib/ransack/nodes/grouping.rb +17 -11
- data/lib/ransack/nodes/sort.rb +9 -5
- data/lib/ransack/nodes/value.rb +74 -68
- data/lib/ransack/nodes.rb +1 -1
- data/lib/ransack/predicate.rb +17 -20
- data/lib/ransack/search.rb +17 -8
- data/lib/ransack/translate.rb +115 -115
- data/lib/ransack/version.rb +1 -1
- data/lib/ransack/visitor.rb +1 -12
- data/lib/ransack.rb +9 -9
- data/logo/ransack-h.png +0 -0
- data/logo/ransack-h.svg +34 -0
- data/logo/ransack-v.png +0 -0
- data/logo/ransack-v.svg +34 -0
- data/logo/ransack.png +0 -0
- data/logo/ransack.svg +21 -0
- data/ransack.gemspec +7 -24
- data/spec/console.rb +4 -0
- data/spec/helpers/polyamorous_helper.rb +19 -0
- data/spec/polyamorous/join_association_spec.rb +35 -0
- data/spec/polyamorous/join_dependency_spec.rb +97 -0
- data/spec/polyamorous/join_spec.rb +19 -0
- data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
- data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
- data/spec/ransack/configuration_spec.rb +97 -14
- data/spec/ransack/helpers/form_builder_spec.rb +2 -11
- data/spec/ransack/helpers/form_helper_spec.rb +481 -113
- data/spec/ransack/nodes/condition_spec.rb +24 -0
- data/spec/ransack/nodes/grouping_spec.rb +56 -0
- data/spec/ransack/predicate_spec.rb +79 -5
- data/spec/ransack/search_spec.rb +207 -81
- data/spec/spec_helper.rb +8 -0
- data/spec/support/schema.rb +100 -42
- metadata +57 -184
- data/.travis.yml +0 -69
- data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
- data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
- data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
- data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
- data/lib/ransack/adapters/active_record/compat.rb +0 -14
- data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
- data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
- data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
- data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
- data/lib/ransack/adapters/mongoid/base.rb +0 -130
- data/lib/ransack/adapters/mongoid/context.rb +0 -208
- data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
- data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
- data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
- data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
- data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
- data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
- data/lib/ransack/adapters/mongoid/table.rb +0 -35
- data/lib/ransack/adapters/mongoid.rb +0 -13
- data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
- data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
- data/spec/mongoid/configuration_spec.rb +0 -102
- data/spec/mongoid/dependencies_spec.rb +0 -8
- data/spec/mongoid/helpers/ransack_helper.rb +0 -11
- data/spec/mongoid/nodes/condition_spec.rb +0 -34
- data/spec/mongoid/nodes/grouping_spec.rb +0 -13
- data/spec/mongoid/predicate_spec.rb +0 -155
- data/spec/mongoid/search_spec.rb +0 -446
- data/spec/mongoid/support/mongoid.yml +0 -6
- data/spec/mongoid/support/schema.rb +0 -128
- data/spec/mongoid/translate_spec.rb +0 -14
- data/spec/mongoid_spec_helper.rb +0 -59
- data/spec/ransack/dependencies_spec.rb +0 -12
@@ -0,0 +1,70 @@
|
|
1
|
+
sk:
|
2
|
+
ransack:
|
3
|
+
search: "vyhľadávanie"
|
4
|
+
predicate: "predikát"
|
5
|
+
and: "a"
|
6
|
+
or: "alebo"
|
7
|
+
any: "akýkoľvek"
|
8
|
+
all: "každý"
|
9
|
+
combinator: "kombinátor"
|
10
|
+
attribute: "atribút"
|
11
|
+
value: "hodnota"
|
12
|
+
condition: "podmienka"
|
13
|
+
sort: "poradie"
|
14
|
+
asc: "vzostupne"
|
15
|
+
desc: "zostupne"
|
16
|
+
predicates:
|
17
|
+
eq: "sa rovná"
|
18
|
+
eq_any: "sa rovná akémukoľvek"
|
19
|
+
eq_all: "sa rovná všetkým"
|
20
|
+
not_eq: "sa nerovná"
|
21
|
+
not_eq_any: "sa nerovná akémukoľvek"
|
22
|
+
not_eq_all: "sa nerovná všetkým"
|
23
|
+
matches: "zodpovedá"
|
24
|
+
matches_any: "zodpovedá akémukoľvek"
|
25
|
+
matches_all: "zodpovedá všetkým"
|
26
|
+
does_not_match: "nezodpovedá"
|
27
|
+
does_not_match_any: "nezodpovedá akémukoľvek"
|
28
|
+
does_not_match_all: "nezodpovedá všetkým"
|
29
|
+
lt: "menší ako"
|
30
|
+
lt_any: "menší ako akýkoľvek"
|
31
|
+
lt_all: "menší ako všetky"
|
32
|
+
lteq: "menší alebo rovný"
|
33
|
+
lteq_any: "menší alebo rovný akémukoľvek"
|
34
|
+
lteq_all: "menší alebo rovný všetkým"
|
35
|
+
gt: "väčší ako"
|
36
|
+
gt_any: "väčší ako akýkoľvek"
|
37
|
+
gt_all: "väčší ako všetky"
|
38
|
+
gteq: "väčší alebo rovný"
|
39
|
+
gteq_any: "väčší alebo rovný akémukoľvek"
|
40
|
+
gteq_all: "väčší alebo rovný všetkým"
|
41
|
+
in: "v"
|
42
|
+
in_any: "v akejkoľvek"
|
43
|
+
in_all: "vo všetkých"
|
44
|
+
not_in: "nie je v"
|
45
|
+
not_in_any: "nie je v akejkoľvek"
|
46
|
+
not_in_all: "nie je vo všetkých"
|
47
|
+
cont: "obsahuje"
|
48
|
+
cont_any: "obsahuje akúkoľvek"
|
49
|
+
cont_all: "obsahuje všetky"
|
50
|
+
not_cont: "neobsahuje"
|
51
|
+
not_cont_any: "neobsahuje akúkoľvek"
|
52
|
+
not_cont_all: "neobsahuje všetky"
|
53
|
+
start: "začína na"
|
54
|
+
start_any: "začína s akoukoľvek"
|
55
|
+
start_all: "začína so všetkými"
|
56
|
+
not_start: "nezačíná s"
|
57
|
+
not_start_any: "nezačíná s akoukoľvek"
|
58
|
+
not_start_all: "nezačíná so všetkými"
|
59
|
+
end: "končí s"
|
60
|
+
end_any: "končí s akoukoľvek"
|
61
|
+
end_all: "končí so všetkými"
|
62
|
+
not_end: "nekončí s"
|
63
|
+
not_end_any: "nekončí s akoukoľvek"
|
64
|
+
not_end_all: "nekončí so všetkými"
|
65
|
+
'true': "je pravdivé"
|
66
|
+
'false': "nie je pravdivé"
|
67
|
+
present: "je vyplnené"
|
68
|
+
blank: "je prázdne"
|
69
|
+
'null': "je null"
|
70
|
+
not_null: "nie je null"
|
@@ -0,0 +1,70 @@
|
|
1
|
+
tr:
|
2
|
+
ransack:
|
3
|
+
search: "ara"
|
4
|
+
predicate: "doğrula"
|
5
|
+
and: "ve"
|
6
|
+
or: "veya"
|
7
|
+
any: "herhangi"
|
8
|
+
all: "hepsi"
|
9
|
+
combinator: "birleştirici"
|
10
|
+
attribute: "nitelik"
|
11
|
+
value: "değer"
|
12
|
+
condition: "şart"
|
13
|
+
sort: "sırala"
|
14
|
+
asc: "artan"
|
15
|
+
desc: "azalan"
|
16
|
+
predicates:
|
17
|
+
eq: "eşit"
|
18
|
+
eq_any: "herhangi birine eşit"
|
19
|
+
eq_all: "hepsine eşit"
|
20
|
+
not_eq: "eşit değil"
|
21
|
+
not_eq_any: "herhangi birine eşit değil"
|
22
|
+
not_eq_all: "hiçbirine eşit değil"
|
23
|
+
matches: "eşleşen"
|
24
|
+
matches_any: "herhangi biri ile eşleşen"
|
25
|
+
matches_all: "hepsi ile eşleşen"
|
26
|
+
does_not_match: "eşleşmeyen"
|
27
|
+
does_not_match_any: "herhangi biri ile eşleşmeyen"
|
28
|
+
does_not_match_all: "hiçbiri ile eşleşmeyen"
|
29
|
+
lt: "daha küçük"
|
30
|
+
lt_any: "herhangi birinden küçük"
|
31
|
+
lt_all: "hepsinden küçük"
|
32
|
+
lteq: "daha küçük veya eşit"
|
33
|
+
lteq_any: "daha küçük veya herhangi birine eşit"
|
34
|
+
lteq_all: "daha küçük veya hepsine eşit"
|
35
|
+
gt: "daha büyük "
|
36
|
+
gt_any: "herhangi birinden daha büyük"
|
37
|
+
gt_all: "hepsinden daha büyük"
|
38
|
+
gteq: "daha büyük veya eşit"
|
39
|
+
gteq_any: "daha büyük veya herhangi birine eşit"
|
40
|
+
gteq_all: "daha büyük veya hepsine eşit"
|
41
|
+
in: "içinde"
|
42
|
+
in_any: "herhangi birinde"
|
43
|
+
in_all: "hepsinde"
|
44
|
+
not_in: "içinde değil"
|
45
|
+
not_in_any: "herhangi birinde değil"
|
46
|
+
not_in_all: "hiçbirinde değil"
|
47
|
+
cont: "içeren"
|
48
|
+
cont_any: "herhangi birini içeren"
|
49
|
+
cont_all: "hepsini içeren"
|
50
|
+
not_cont: "içermeyen"
|
51
|
+
not_cont_any: "herhangi birini içermeyen"
|
52
|
+
not_cont_all: "hiçbirini birini içermeyen"
|
53
|
+
start: "ile başlayan"
|
54
|
+
start_any: "herhangi biriyle başlayan"
|
55
|
+
start_all: "hepsiyle başlayan"
|
56
|
+
not_start: "ile başlamayan"
|
57
|
+
not_start_any: "herhangi biriyle başlamayan"
|
58
|
+
not_start_all: "hiçbiriyle başlamayan"
|
59
|
+
end: "ile biten"
|
60
|
+
end_any: "herhangi biriyle biten"
|
61
|
+
end_all: "hepsi ile biten"
|
62
|
+
not_end: "ile bitmeyen"
|
63
|
+
not_end_any: "herhangi biriyle bitmeyen"
|
64
|
+
not_end_all: "hiçbiriyle bitmeyen"
|
65
|
+
'true': "doğru"
|
66
|
+
'false': "yanlış"
|
67
|
+
present: "mevcut"
|
68
|
+
blank: "boş"
|
69
|
+
'null': "geçersiz"
|
70
|
+
not_null: "geçerli"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
zh:
|
1
|
+
zh-CN:
|
2
2
|
ransack:
|
3
3
|
search: "搜索"
|
4
4
|
predicate: "基于(predicate)"
|
@@ -50,18 +50,18 @@ zh:
|
|
50
50
|
not_cont: "不包含"
|
51
51
|
not_cont_any: "不包含任意一个值"
|
52
52
|
not_cont_all: "不包含所有值"
|
53
|
-
start: "
|
54
|
-
start_any: "
|
55
|
-
start_all: "
|
56
|
-
not_start: "
|
57
|
-
not_start_any: "
|
58
|
-
not_start_all: "
|
59
|
-
end: "
|
60
|
-
end_any: "
|
61
|
-
end_all: "
|
62
|
-
not_end: "
|
63
|
-
not_end_any: "
|
64
|
-
not_end_all: "
|
53
|
+
start: "始于"
|
54
|
+
start_any: "始于任一值"
|
55
|
+
start_all: "始于任意值"
|
56
|
+
not_start: "非始于"
|
57
|
+
not_start_any: "非始于任一值"
|
58
|
+
not_start_all: "非始于任意值"
|
59
|
+
end: "止于"
|
60
|
+
end_any: "止于任一值"
|
61
|
+
end_all: "止于任意值"
|
62
|
+
not_end: "非止于"
|
63
|
+
not_end_any: "非止于任一值"
|
64
|
+
not_end_all: "非止于任意值"
|
65
65
|
'true': "等于true"
|
66
66
|
'false': "等于false"
|
67
67
|
present: "有值"
|
@@ -0,0 +1,70 @@
|
|
1
|
+
zh-TW:
|
2
|
+
ransack:
|
3
|
+
search: "搜尋"
|
4
|
+
predicate: "基於"
|
5
|
+
and: "而且"
|
6
|
+
or: "或者"
|
7
|
+
any: "任何"
|
8
|
+
all: "所有"
|
9
|
+
combinator: "條件組合"
|
10
|
+
attribute: "屬性"
|
11
|
+
value: "數值"
|
12
|
+
condition: "條件"
|
13
|
+
sort: "排序"
|
14
|
+
asc: "升冪排序"
|
15
|
+
desc: "降冪排序"
|
16
|
+
predicates:
|
17
|
+
eq: "等於"
|
18
|
+
eq_any: "等於任何一個值"
|
19
|
+
eq_all: "等於所有值"
|
20
|
+
not_eq: "不等於"
|
21
|
+
not_eq_any: "不等於任何一個值"
|
22
|
+
not_eq_all: "不等於所有值"
|
23
|
+
matches: "符合"
|
24
|
+
matches_any: "符合任何一個條件"
|
25
|
+
matches_all: "符合所有條件"
|
26
|
+
does_not_match: "不符合"
|
27
|
+
does_not_match_any: "不符合任何一個條件"
|
28
|
+
does_not_match_all: "不符合所有條件"
|
29
|
+
lt: "小於"
|
30
|
+
lt_any: "小於任何一個值"
|
31
|
+
lt_all: "小於所有值"
|
32
|
+
lteq: "小於或等於"
|
33
|
+
lteq_any: "小於或等於任何一個值"
|
34
|
+
lteq_all: "小於或等於所有值"
|
35
|
+
gt: "大於"
|
36
|
+
gt_any: "大於任何一個值"
|
37
|
+
gt_all: "大於所有值"
|
38
|
+
gteq: "大於或等於"
|
39
|
+
gteq_any: "大於或等於任何一個值"
|
40
|
+
gteq_all: "大於或等於所有值"
|
41
|
+
in: "被包含於"
|
42
|
+
in_any: "被包含於任何一個值"
|
43
|
+
in_all: "被包含於所有值"
|
44
|
+
not_in: "不被包含於"
|
45
|
+
not_in_any: "不被包含於任何一個值"
|
46
|
+
not_in_all: "不被包含於所有值"
|
47
|
+
cont: "包含"
|
48
|
+
cont_any: "包含任何一個值"
|
49
|
+
cont_all: "包含所有值"
|
50
|
+
not_cont: "不包含"
|
51
|
+
not_cont_any: "不包含任何一個值"
|
52
|
+
not_cont_all: "不包含所有值"
|
53
|
+
start: "以某個值開始"
|
54
|
+
start_any: "以任何一個值開始"
|
55
|
+
start_all: "以所有值開始"
|
56
|
+
not_start: "不以某個值開始"
|
57
|
+
not_start_any: "不以任何一值開始"
|
58
|
+
not_start_all: "不以所有值開始"
|
59
|
+
end: "以某個值結尾"
|
60
|
+
end_any: "以任何一個值結尾"
|
61
|
+
end_all: "以所有值結尾"
|
62
|
+
not_end: "不以某個值結尾"
|
63
|
+
not_end_any: "不以任何一個值結尾"
|
64
|
+
not_end_all: "不以所有值結尾"
|
65
|
+
'true': "為真"
|
66
|
+
'false': "為假"
|
67
|
+
present: "有值"
|
68
|
+
blank: "為空"
|
69
|
+
'null': "為 null"
|
70
|
+
not_null: "不為 null"
|
@@ -5,7 +5,7 @@ module Ransack
|
|
5
5
|
|
6
6
|
attr_reader :name, :ransacker_args
|
7
7
|
|
8
|
-
delegate :blank?, :present?,
|
8
|
+
delegate :blank?, :present?, :to => :name
|
9
9
|
delegate :engine, :to => :context
|
10
10
|
|
11
11
|
def initialize(context, name = nil, ransacker_args = [])
|
@@ -16,7 +16,6 @@ module Ransack
|
|
16
16
|
|
17
17
|
def name=(name)
|
18
18
|
@name = name
|
19
|
-
context.bind(self, name) unless name.blank?
|
20
19
|
end
|
21
20
|
|
22
21
|
def valid?
|
@@ -25,6 +24,10 @@ module Ransack
|
|
25
24
|
.include?(attr_name.split('.').last)
|
26
25
|
end
|
27
26
|
|
27
|
+
def associated_collection?
|
28
|
+
parent.respond_to?(:reflection) && parent.reflection.collection?
|
29
|
+
end
|
30
|
+
|
28
31
|
def type
|
29
32
|
if ransacker
|
30
33
|
return ransacker.type
|
@@ -27,14 +27,26 @@ module Ransack
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
30
|
+
def get_arel_attribute
|
31
|
+
if ransacker
|
32
|
+
ransacker.attr_from(self)
|
33
|
+
else
|
34
|
+
get_attribute
|
36
35
|
end
|
36
|
+
end
|
37
37
|
|
38
|
+
def get_attribute
|
39
|
+
if is_alias_attribute?
|
40
|
+
context.table_for(parent)[parent.base_klass.attribute_aliases[attr_name]]
|
41
|
+
else
|
42
|
+
context.table_for(parent)[attr_name]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_alias_attribute?
|
47
|
+
Ransack::SUPPORTS_ATTRIBUTE_ALIAS &&
|
48
|
+
parent.base_klass.attribute_aliases.key?(attr_name)
|
49
|
+
end
|
38
50
|
end
|
39
51
|
end
|
40
52
|
end
|
@@ -9,9 +9,10 @@ module Ransack
|
|
9
9
|
|
10
10
|
class << self
|
11
11
|
def extract(context, key, values)
|
12
|
-
attributes, predicate =
|
12
|
+
attributes, predicate, combinator =
|
13
|
+
extract_values_for_condition(key, context)
|
14
|
+
|
13
15
|
if attributes.size > 0 && predicate
|
14
|
-
combinator = key.match(/_(or|and)_/) ? $1 : nil
|
15
16
|
condition = self.new(context)
|
16
17
|
condition.build(
|
17
18
|
:a => attributes,
|
@@ -31,20 +32,34 @@ module Ransack
|
|
31
32
|
|
32
33
|
private
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
def extract_values_for_condition(key, context = nil)
|
36
|
+
str = key.dup
|
37
|
+
name = Predicate.detect_and_strip_from_string!(str)
|
38
|
+
predicate = Predicate.named(name)
|
39
|
+
|
40
|
+
unless predicate || Ransack.options[:ignore_unknown_conditions]
|
41
|
+
raise ArgumentError, "No valid predicate for #{key}"
|
42
|
+
end
|
43
|
+
|
44
|
+
if context.present?
|
45
|
+
str = context.ransackable_alias(str)
|
46
|
+
end
|
47
|
+
|
48
|
+
combinator =
|
49
|
+
if str.match(/_(or|and)_/)
|
50
|
+
$1
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
if context.present? && context.attribute_method?(str)
|
56
|
+
attributes = [str]
|
57
|
+
else
|
58
|
+
attributes = str.split(/_and_|_or_/)
|
59
|
+
end
|
60
|
+
|
61
|
+
[attributes, predicate, combinator]
|
45
62
|
end
|
46
|
-
[attributes, predicate]
|
47
|
-
end
|
48
63
|
end
|
49
64
|
|
50
65
|
def valid?
|
@@ -64,14 +79,12 @@ module Ransack
|
|
64
79
|
def attributes=(args)
|
65
80
|
case args
|
66
81
|
when Array
|
67
|
-
args.each do |
|
68
|
-
|
69
|
-
self.attributes << attr if attr.valid?
|
82
|
+
args.each do |name|
|
83
|
+
build_attribute(name)
|
70
84
|
end
|
71
85
|
when Hash
|
72
86
|
args.each do |index, attrs|
|
73
|
-
|
74
|
-
self.attributes << attr if attr.valid?
|
87
|
+
build_attribute(attrs[:name], attrs[:ransacker_args])
|
75
88
|
end
|
76
89
|
else
|
77
90
|
raise ArgumentError,
|
@@ -114,9 +127,32 @@ module Ransack
|
|
114
127
|
alias :m= :combinator=
|
115
128
|
alias :m :combinator
|
116
129
|
|
117
|
-
|
118
|
-
|
119
|
-
|
130
|
+
|
131
|
+
# == build_attribute
|
132
|
+
#
|
133
|
+
# This method was originally called from Nodes::Grouping#new_condition
|
134
|
+
# only, without arguments, without #valid? checking, to build a new
|
135
|
+
# grouping condition.
|
136
|
+
#
|
137
|
+
# After refactoring in 235eae3, it is now called from 2 places:
|
138
|
+
#
|
139
|
+
# 1. Nodes::Condition#attributes=, with +name+ argument passed or +name+
|
140
|
+
# and +ransacker_args+. Attributes are included only if #valid?.
|
141
|
+
#
|
142
|
+
# 2. Nodes::Grouping#new_condition without arguments. In this case, the
|
143
|
+
# #valid? conditional needs to be bypassed, otherwise nothing is
|
144
|
+
# built. The `name.nil?` conditional below currently does this.
|
145
|
+
#
|
146
|
+
# TODO: Add test coverage for this behavior and ensure that `name.nil?`
|
147
|
+
# isn't fixing issue #701 by introducing untested regressions.
|
148
|
+
#
|
149
|
+
def build_attribute(name = nil, ransacker_args = [])
|
150
|
+
Attribute.new(@context, name, ransacker_args).tap do |attribute|
|
151
|
+
@context.bind(attribute, attribute.name)
|
152
|
+
self.attributes << attribute if name.nil? || attribute.valid?
|
153
|
+
if predicate && !negative?
|
154
|
+
@context.lock_association(attribute.parent)
|
155
|
+
end
|
120
156
|
end
|
121
157
|
end
|
122
158
|
|
@@ -168,6 +204,10 @@ module Ransack
|
|
168
204
|
|
169
205
|
def predicate_name=(name)
|
170
206
|
self.predicate = Predicate.named(name)
|
207
|
+
unless negative?
|
208
|
+
attributes.each { |a| context.lock_association(a.parent) }
|
209
|
+
end
|
210
|
+
@predicate
|
171
211
|
end
|
172
212
|
alias :p= :predicate_name=
|
173
213
|
|
@@ -196,20 +236,33 @@ module Ransack
|
|
196
236
|
val = predicate.format(val)
|
197
237
|
val
|
198
238
|
end
|
199
|
-
predicate.wants_array
|
239
|
+
if predicate.wants_array
|
240
|
+
formatted
|
241
|
+
else
|
242
|
+
formatted.first
|
243
|
+
end
|
200
244
|
end
|
201
245
|
|
202
246
|
def arel_predicate_for_attribute(attr)
|
203
247
|
if predicate.arel_predicate === Proc
|
204
248
|
values = casted_values_for_attribute(attr)
|
205
|
-
predicate.
|
206
|
-
|
207
|
-
|
249
|
+
unless predicate.wants_array
|
250
|
+
values = values.first
|
251
|
+
end
|
252
|
+
predicate.arel_predicate.call(values)
|
208
253
|
else
|
209
254
|
predicate.arel_predicate
|
210
255
|
end
|
211
256
|
end
|
212
257
|
|
258
|
+
def attr_value_for_attribute(attr)
|
259
|
+
return attr.attr if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
|
260
|
+
|
261
|
+
predicate.case_insensitive ? attr.attr.lower : attr.attr
|
262
|
+
rescue
|
263
|
+
attr.attr
|
264
|
+
end
|
265
|
+
|
213
266
|
|
214
267
|
def default_type
|
215
268
|
predicate.type || (attributes.first && attributes.first.type)
|
@@ -224,10 +277,14 @@ module Ransack
|
|
224
277
|
]
|
225
278
|
.reject { |e| e[1].blank? }
|
226
279
|
.map { |v| "#{v[0]}: #{v[1]}" }
|
227
|
-
.join(
|
280
|
+
.join(', '.freeze)
|
228
281
|
"Condition <#{data}>"
|
229
282
|
end
|
230
283
|
|
284
|
+
def negative?
|
285
|
+
predicate.negative?
|
286
|
+
end
|
287
|
+
|
231
288
|
private
|
232
289
|
|
233
290
|
def valid_combinator?
|
@@ -44,16 +44,12 @@ module Ransack
|
|
44
44
|
self.conditions << condition if condition.valid?
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
remove_duplicate_conditions!
|
48
48
|
end
|
49
49
|
alias :c= :conditions=
|
50
50
|
|
51
51
|
def [](key)
|
52
|
-
|
53
|
-
condition
|
54
|
-
else
|
55
|
-
nil
|
56
|
-
end
|
52
|
+
conditions.detect { |c| c.key == key.to_s }
|
57
53
|
end
|
58
54
|
|
59
55
|
def []=(key, value)
|
@@ -68,7 +64,6 @@ module Ransack
|
|
68
64
|
def respond_to?(method_id)
|
69
65
|
super or begin
|
70
66
|
method_name = method_id.to_s
|
71
|
-
writer = method_name.sub!(/\=$/, Constants::EMPTY)
|
72
67
|
attribute_method?(method_name) ? true : false
|
73
68
|
end
|
74
69
|
end
|
@@ -113,8 +108,8 @@ module Ransack
|
|
113
108
|
alias :g= :groupings=
|
114
109
|
|
115
110
|
def method_missing(method_id, *args)
|
116
|
-
method_name = method_id.to_s
|
117
|
-
writer = method_name.sub!(/\=$/,
|
111
|
+
method_name = method_id.to_s.dup
|
112
|
+
writer = method_name.sub!(/\=$/, ''.freeze)
|
118
113
|
if attribute_method?(method_name)
|
119
114
|
if writer
|
120
115
|
write_attribute(method_name, *args)
|
@@ -169,7 +164,7 @@ module Ransack
|
|
169
164
|
]
|
170
165
|
.reject { |e| e[1].blank? }
|
171
166
|
.map { |v| "#{v[0]}: #{v[1]}" }
|
172
|
-
.join(
|
167
|
+
.join(', '.freeze)
|
173
168
|
"Grouping <#{data}>"
|
174
169
|
end
|
175
170
|
|
@@ -191,10 +186,21 @@ module Ransack
|
|
191
186
|
end
|
192
187
|
|
193
188
|
def strip_predicate_and_index(str)
|
194
|
-
string = str
|
189
|
+
string = str[/(.+?)\(/, 1] || str.dup
|
195
190
|
Predicate.detect_and_strip_from_string!(string)
|
196
191
|
string
|
197
192
|
end
|
193
|
+
|
194
|
+
def remove_duplicate_conditions!
|
195
|
+
# If self.conditions.uniq! is called without passing a block, then
|
196
|
+
# conditions differing only by ransacker_args within attributes are
|
197
|
+
# wrongly considered equal and are removed.
|
198
|
+
self.conditions.uniq! do |c|
|
199
|
+
c.attributes.map { |a| [a.name, a.ransacker_args] }.flatten +
|
200
|
+
[c.predicate.name] +
|
201
|
+
c.values.map { |v| v.value }
|
202
|
+
end
|
203
|
+
end
|
198
204
|
end
|
199
205
|
end
|
200
206
|
end
|
data/lib/ransack/nodes/sort.rb
CHANGED
@@ -3,7 +3,7 @@ module Ransack
|
|
3
3
|
class Sort < Node
|
4
4
|
include Bindable
|
5
5
|
|
6
|
-
attr_reader :name, :dir
|
6
|
+
attr_reader :name, :dir, :ransacker_args
|
7
7
|
i18n_word :asc, :desc
|
8
8
|
|
9
9
|
class << self
|
@@ -16,7 +16,7 @@ module Ransack
|
|
16
16
|
|
17
17
|
def build(params)
|
18
18
|
params.with_indifferent_access.each do |key, value|
|
19
|
-
if key.match(/^(name|dir)$/)
|
19
|
+
if key.match(/^(name|dir|ransacker_args)$/)
|
20
20
|
self.send("#{key}=", value)
|
21
21
|
end
|
22
22
|
end
|
@@ -32,19 +32,23 @@ module Ransack
|
|
32
32
|
|
33
33
|
def name=(name)
|
34
34
|
@name = name
|
35
|
-
context.bind(self, name)
|
35
|
+
context.bind(self, name)
|
36
36
|
end
|
37
37
|
|
38
38
|
def dir=(dir)
|
39
39
|
dir = dir.downcase if dir
|
40
40
|
@dir =
|
41
|
-
if
|
41
|
+
if dir == 'asc'.freeze || dir == 'desc'.freeze
|
42
42
|
dir
|
43
43
|
else
|
44
|
-
|
44
|
+
'asc'.freeze
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
def ransacker_args=(ransack_args)
|
49
|
+
@ransacker_args = ransack_args
|
50
|
+
end
|
51
|
+
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|