ransack 2.1.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +13 -1
  4. data/CHANGELOG.md +24 -0
  5. data/Gemfile +4 -12
  6. data/README.md +5 -3
  7. data/lib/ransack.rb +1 -0
  8. data/lib/ransack/adapters/active_record/context.rb +40 -12
  9. data/lib/ransack/adapters/active_record/ransack/constants.rb +5 -2
  10. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +1 -1
  11. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -1
  12. data/lib/ransack/constants.rb +1 -0
  13. data/lib/ransack/context.rb +19 -18
  14. data/lib/ransack/helpers/form_helper.rb +1 -1
  15. data/lib/ransack/locale/az.yml +1 -1
  16. data/lib/ransack/locale/ca.yml +70 -0
  17. data/lib/ransack/locale/es.yml +22 -22
  18. data/lib/ransack/locale/fa.yml +70 -0
  19. data/lib/ransack/locale/fi.yml +71 -0
  20. data/lib/ransack/translate.rb +115 -115
  21. data/lib/ransack/version.rb +1 -1
  22. data/{lib → polyamorous/lib}/polyamorous.rb +7 -3
  23. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.0_ruby_2/join_association.rb +0 -0
  24. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +0 -0
  25. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.1_ruby_2/join_association.rb +1 -2
  26. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +0 -0
  27. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +2 -3
  28. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +1 -2
  29. data/polyamorous/lib/polyamorous/activerecord_5.2.0_ruby_2/reflection.rb +12 -0
  30. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.2.1_ruby_2/join_association.rb +0 -9
  31. data/{lib → polyamorous/lib}/polyamorous/activerecord_5.2.1_ruby_2/join_dependency.rb +25 -1
  32. data/polyamorous/lib/polyamorous/activerecord_5.2.1_ruby_2/reflection.rb +2 -0
  33. data/polyamorous/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +2 -0
  34. data/polyamorous/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +81 -0
  35. data/polyamorous/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +2 -0
  36. data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +2 -0
  37. data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +2 -0
  38. data/polyamorous/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +2 -0
  39. data/{lib → polyamorous/lib}/polyamorous/join.rb +0 -0
  40. data/{lib → polyamorous/lib}/polyamorous/swapping_reflection_class.rb +0 -0
  41. data/{lib → polyamorous/lib}/polyamorous/tree_node.rb +0 -0
  42. data/polyamorous/lib/polyamorous/version.rb +3 -0
  43. data/polyamorous/polyamorous.gemspec +35 -0
  44. data/ransack.gemspec +3 -3
  45. data/spec/helpers/polyamorous_helper.rb +6 -2
  46. data/spec/ransack/adapters/active_record/context_spec.rb +41 -0
  47. data/spec/ransack/join_dependency_spec.rb +18 -7
  48. data/spec/ransack/predicate_spec.rb +16 -2
  49. data/spec/ransack/search_spec.rb +26 -2
  50. data/spec/spec_helper.rb +1 -0
  51. data/spec/support/schema.rb +6 -0
  52. metadata +58 -18
@@ -6,11 +6,11 @@ es:
6
6
  or: "o"
7
7
  any: "cualquier"
8
8
  all: "todos"
9
- combinator: "combinado"
9
+ combinator: "combinador"
10
10
  attribute: "atributo"
11
11
  value: "valor"
12
12
  condition: "condición"
13
- sort: "ordernar"
13
+ sort: "ordenar"
14
14
  asc: "ascendente"
15
15
  desc: "descendente"
16
16
  predicates:
@@ -19,12 +19,12 @@ es:
19
19
  eq_all: "es igual a todos"
20
20
  not_eq: "no es igual a"
21
21
  not_eq_any: "no es igual a cualquier"
22
- not_eq_all: "no es iguala todos"
23
- matches: "coincidir"
24
- matches_any: "coincidir a cualquier"
25
- matches_all: "coincidir a todos"
26
- does_not_match: "no coincide"
27
- does_not_match_any: "no coincide con ninguna"
22
+ not_eq_all: "no es igual a todos"
23
+ matches: "coincide con"
24
+ matches_any: "coincide con cualquier"
25
+ matches_all: "coincide con todos"
26
+ does_not_match: "no coincide con"
27
+ does_not_match_any: "no coincide con ninguno"
28
28
  does_not_match_all: "no coincide con todos"
29
29
  lt: "menor que"
30
30
  lt_any: "menor que cualquier"
@@ -48,23 +48,23 @@ es:
48
48
  cont_any: "contiene cualquier"
49
49
  cont_all: "contiene todos"
50
50
  not_cont: "no contiene"
51
- not_cont_any: "no contiene ninguna"
52
- not_cont_all: "no contiene toda"
51
+ not_cont_any: "no contiene ninguno"
52
+ not_cont_all: "no contiene todos"
53
53
  start: "comienza con"
54
54
  start_any: "comienza con cualquier"
55
- start_all: "comienza con toda"
56
- not_start: "no inicia con"
55
+ start_all: "comienza con todos"
56
+ not_start: "no comienza con"
57
57
  not_start_any: "no comienza con cualquier"
58
- not_start_all: "no inicia con toda"
59
- end: "termina con"
60
- end_any: "termina con cualquier"
61
- end_all: "termina con todo"
62
- not_end: "no termina con"
63
- not_end_any: "no termina con cualquier"
64
- not_end_all: "no termina con todo"
58
+ not_start_all: "no comienza con todos"
59
+ end: "termina en"
60
+ end_any: "termina en cualquier"
61
+ end_all: "termina en todos"
62
+ not_end: "no termina en"
63
+ not_end_any: "no termina en cualquier"
64
+ not_end_all: "no termina en todos"
65
65
  'true': "es verdadero"
66
66
  'false': "es falso"
67
- present: "es presente"
67
+ present: "está presente"
68
68
  blank: "está en blanco"
69
- 'null': "es nula"
70
- not_null: "no es nula"
69
+ 'null': "es nulo"
70
+ not_null: "no es nulo"
@@ -0,0 +1,70 @@
1
+ fa:
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': "صفر است"
70
+ not_null: "صفر نیست"
@@ -0,0 +1,71 @@
1
+ fi:
2
+ ransack:
3
+ search: "haku"
4
+ predicate: "predikaatti"
5
+ and: "ja"
6
+ or: "tai"
7
+ any: "jokin"
8
+ all: "kaikki"
9
+ combinator: "kombinaattori"
10
+ attribute: "attribuutti"
11
+ value: "arvo"
12
+ condition: "ehto"
13
+ sort: "järjestys"
14
+ asc: "nouseva"
15
+ desc: "laskeva"
16
+ predicates:
17
+ eq: "sama kuin"
18
+ eq_any: "sama kuin jokin"
19
+ eq_all: "sama kuin kaikki"
20
+ not_eq: "eri kuin"
21
+ not_eq_any: "eri kuin jokin"
22
+ not_eq_all: "eri kuin kaikki"
23
+ matches: "täsmää"
24
+ matches_any: "täsmää jonkun kanssa"
25
+ matches_all: "täsmää kaikkien kanssa"
26
+ does_not_match: "ei täsmää"
27
+ does_not_match_any: "ei täsmää minkään kanssa"
28
+ does_not_match_all: "ei täsmää kaikkien kanssa"
29
+ lt: "vähemmän kuin"
30
+ lt_any: "vähemmän kuin jokin"
31
+ lt_all: "vähemmän kuin mikään"
32
+ lteq: "vähemmän tai sama kuin"
33
+ lteq_any: "vähemmän tai sama kuin jokin"
34
+ lteq_all: "vähemmän tai sama kuin mikään"
35
+ gt: "suurempi kuin"
36
+ gt_any: "suurempi kuin jokin"
37
+ gt_all: "suurempi kuin mikään"
38
+ gteq: "suurempi tai yhtä suuri kuin"
39
+ gteq_any: "suurempi tai yhtä suuri kuin jokin"
40
+ gteq_all: "suurempi tai yhtä suuri kuin mikään"
41
+ in: "kohteessa"
42
+ in_any: "jossakin kohteessa"
43
+ in_all: "kaikissa kohteissa"
44
+ not_in: "ei kohteessa"
45
+ not_in_any: "ei jossakin kohteista"
46
+ not_in_all: "ei missään kohteista"
47
+ cont: "sisältää"
48
+ cont_any: "sisältää jonkin"
49
+ cont_all: "sisältää kaikki"
50
+ not_cont: "ei sisällä"
51
+ not_cont_any: "ei sisällä jotakin"
52
+ not_cont_all: "ei sisällä mitään"
53
+ start: "alkaa"
54
+ start_any: "alkaa jollakin"
55
+ start_all: "alkaa kaikilla"
56
+ not_start: "ei ala"
57
+ not_start_any: "ei ala jollakin"
58
+ not_start_all: "ei ala millään"
59
+ end: "päättyy"
60
+ end_any: "päättyy jollakin"
61
+ end_all: "päättyy millään"
62
+ not_end: "ei pääty"
63
+ not_end_any: "ei pääty jollakin"
64
+ not_end_all: "ei pääty millään"
65
+ 'true': "on tosi"
66
+ 'false': "ei ole tosi"
67
+ present: "on läsnä"
68
+ blank: "on tyhjä"
69
+ 'null': "on määrittämätön"
70
+ not_null: "on määritetty"
71
+
@@ -6,151 +6,151 @@ I18n.load_path += Dir[
6
6
 
7
7
  module Ransack
8
8
  module Translate
9
- def self.word(key, options = {})
10
- I18n.translate(:"ransack.#{key}", :default => key.to_s)
11
- end
12
-
13
- def self.predicate(key, options = {})
14
- I18n.translate(:"ransack.predicates.#{key}", :default => key.to_s)
15
- end
16
-
17
- def self.attribute(key, options = {})
18
- unless context = options.delete(:context)
19
- raise ArgumentError, "A context is required to translate attributes"
9
+ class << self
10
+ def word(key, options = {})
11
+ I18n.translate(:"ransack.#{key}", default: key.to_s)
20
12
  end
21
13
 
22
- original_name = key.to_s
23
- base_class = context.klass
24
- base_ancestors = base_class.ancestors.select {
25
- |x| x.respond_to?(:model_name)
26
- }
27
- attributes_str = original_name.dup # will be modified by ⬇
28
- predicate = Predicate.detect_and_strip_from_string!(attributes_str)
29
- attribute_names = attributes_str.split(/_and_|_or_/)
30
- combinator = attributes_str.match(/_and_/) ? :and : :or
31
- defaults = base_ancestors.map do |klass|
32
- "ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
14
+ def predicate(key, options = {})
15
+ I18n.translate(:"ransack.predicates.#{key}", default: key.to_s)
33
16
  end
34
17
 
35
- translated_names = attribute_names.map do |name|
36
- attribute_name(context, name, options[:include_associations])
37
- end
18
+ def attribute(key, options = {})
19
+ unless context = options.delete(:context)
20
+ raise ArgumentError, "A context is required to translate attributes"
21
+ end
38
22
 
39
- interpolations = {
40
- :attributes => translated_names.join(" #{Translate.word(combinator)} ")
41
- }
23
+ original_name = key.to_s
24
+ base_class = context.klass
25
+ base_ancestors = base_class.ancestors.select {
26
+ |x| x.respond_to?(:model_name)
27
+ }
28
+ attributes_str = original_name.dup # will be modified by ⬇
29
+ predicate = Predicate.detect_and_strip_from_string!(attributes_str)
30
+ attribute_names = attributes_str.split(/_and_|_or_/)
31
+ combinator = attributes_str =~ /_and_/ ? :and : :or
32
+ defaults = base_ancestors.map do |klass|
33
+ "ransack.attributes.#{i18n_key(klass)}.#{original_name}".to_sym
34
+ end
42
35
 
43
- if predicate
44
- defaults << "%{attributes} %{predicate}".freeze
45
- interpolations[:predicate] = Translate.predicate(predicate)
46
- else
47
- defaults << "%{attributes}".freeze
48
- end
36
+ translated_names = attribute_names.map do |name|
37
+ attribute_name(context, name, options[:include_associations])
38
+ end
49
39
 
50
- defaults << options.delete(:default) if options[:default]
51
- options.reverse_merge! :count => 1, :default => defaults
52
- I18n.translate(defaults.shift, options.merge(interpolations))
53
- end
40
+ interpolations = {
41
+ attributes: translated_names.join(" #{Translate.word(combinator)} ")
42
+ }
54
43
 
55
- def self.association(key, options = {})
56
- unless context = options.delete(:context)
57
- raise ArgumentError, "A context is required to translate associations"
44
+ if predicate
45
+ defaults << "%{attributes} %{predicate}".freeze
46
+ interpolations[:predicate] = Translate.predicate(predicate)
47
+ else
48
+ defaults << "%{attributes}".freeze
49
+ end
50
+
51
+ defaults << options.delete(:default) if options[:default]
52
+ options.reverse_merge! count: 1, default: defaults
53
+ I18n.translate(defaults.shift, options.merge(interpolations))
58
54
  end
59
55
 
60
- defaults =
61
- if key.blank?
62
- [:"ransack.models.#{i18n_key(context.klass)}",
63
- :"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
64
- else
65
- [:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
56
+ def association(key, options = {})
57
+ unless context = options.delete(:context)
58
+ raise ArgumentError, "A context is required to translate associations"
66
59
  end
67
- defaults << context.traverse(key).model_name.human
68
- options = { :count => 1, :default => defaults }
69
- I18n.translate(defaults.shift, options)
70
- end
71
60
 
72
- private
61
+ defaults =
62
+ if key.blank?
63
+ [:"ransack.models.#{i18n_key(context.klass)}",
64
+ :"#{context.klass.i18n_scope}.models.#{i18n_key(context.klass)}"]
65
+ else
66
+ [:"ransack.associations.#{i18n_key(context.klass)}.#{key}"]
67
+ end
68
+ defaults << context.traverse(key).model_name.human
69
+ options = { :count => 1, :default => defaults }
70
+ I18n.translate(defaults.shift, options)
71
+ end
73
72
 
74
- def self.attribute_name(context, name, include_associations = nil)
75
- @context, @name = context, name
76
- @assoc_path = context.association_path(name)
77
- @attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
78
- associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
79
- @include_associated = include_associations && associated_class
73
+ private
80
74
 
81
- defaults = default_attribute_name << fallback_args
82
- options = { :count => 1, :default => defaults }
83
- interpolations = build_interpolations(associated_class)
75
+ def attribute_name(context, name, include_associations = nil)
76
+ @context, @name = context, name
77
+ @assoc_path = context.association_path(name)
78
+ @attr_name = @name.sub(/^#{@assoc_path}_/, ''.freeze)
79
+ associated_class = @context.traverse(@assoc_path) if @assoc_path.present?
80
+ @include_associated = include_associations && associated_class
84
81
 
85
- I18n.translate(defaults.shift, options.merge(interpolations))
86
- end
82
+ defaults = default_attribute_name << fallback_args
83
+ options = { count: 1, default: defaults }
84
+ interpolations = build_interpolations(associated_class)
87
85
 
88
- def self.default_attribute_name
89
- ["ransack.attributes.#{i18n_key(@context.klass)}.#{@name}".to_sym]
90
- end
86
+ I18n.translate(defaults.shift, options.merge(interpolations))
87
+ end
91
88
 
92
- def self.fallback_args
93
- if @include_associated
94
- '%{association_name} %{attr_fallback_name}'.freeze
95
- else
96
- '%{attr_fallback_name}'.freeze
89
+ def default_attribute_name
90
+ ["ransack.attributes.#{i18n_key(@context.klass)}.#{@name}".to_sym]
97
91
  end
98
- end
99
92
 
100
- def self.build_interpolations(associated_class)
101
- {
102
- :attr_fallback_name => attr_fallback_name(associated_class),
103
- :association_name => association_name
104
- }
105
- .reject { |_, value| value.nil? }
106
- end
93
+ def fallback_args
94
+ if @include_associated
95
+ '%{association_name} %{attr_fallback_name}'.freeze
96
+ else
97
+ '%{attr_fallback_name}'.freeze
98
+ end
99
+ end
107
100
 
108
- def self.attr_fallback_name(associated_class)
109
- I18n.t(
110
- :"ransack.attributes.#{fallback_class(associated_class)}.#{@attr_name}",
111
- :default => default_interpolation(associated_class)
101
+ def build_interpolations(associated_class)
102
+ {
103
+ attr_fallback_name: attr_fallback_name(associated_class),
104
+ association_name: association_name
105
+ }.reject { |_, value| value.nil? }
106
+ end
107
+
108
+ def attr_fallback_name(associated_class)
109
+ I18n.t(
110
+ :"ransack.attributes.#{fallback_class(associated_class)}.#{@attr_name}",
111
+ default: default_interpolation(associated_class)
112
112
  )
113
- end
113
+ end
114
114
 
115
- def self.fallback_class(associated_class)
116
- i18n_key(associated_class || @context.klass)
117
- end
115
+ def fallback_class(associated_class)
116
+ i18n_key(associated_class || @context.klass)
117
+ end
118
118
 
119
- def self.association_name
120
- association(@assoc_path, :context => @context) if @include_associated
121
- end
119
+ def association_name
120
+ association(@assoc_path, context: @context) if @include_associated
121
+ end
122
122
 
123
- def self.default_interpolation(associated_class)
124
- [
125
- associated_attribute(associated_class),
126
- ".attributes.#{@attr_name}".to_sym,
127
- @attr_name.humanize
128
- ]
129
- .flatten
130
- end
123
+ def default_interpolation(associated_class)
124
+ [
125
+ associated_attribute(associated_class),
126
+ ".attributes.#{@attr_name}".to_sym,
127
+ @attr_name.humanize
128
+ ].flatten
129
+ end
131
130
 
132
- def self.associated_attribute(associated_class)
133
- if associated_class
134
- translated_attribute(associated_class)
135
- else
136
- translated_ancestor_attributes
131
+ def associated_attribute(associated_class)
132
+ if associated_class
133
+ translated_attribute(associated_class)
134
+ else
135
+ translated_ancestor_attributes
136
+ end
137
137
  end
138
- end
139
138
 
140
- def self.translated_attribute(associated_class)
141
- key = "#{associated_class.i18n_scope}.attributes.#{
139
+ def translated_attribute(associated_class)
140
+ key = "#{associated_class.i18n_scope}.attributes.#{
142
141
  i18n_key(associated_class)}.#{@attr_name}"
143
- ["#{key}.one".to_sym, key.to_sym]
144
- end
142
+ ["#{key}.one".to_sym, key.to_sym]
143
+ end
145
144
 
146
- def self.translated_ancestor_attributes
147
- @context.klass.ancestors
148
- .select { |ancestor| ancestor.respond_to?(:model_name) }
149
- .map { |ancestor| translated_attribute(ancestor) }
150
- end
145
+ def translated_ancestor_attributes
146
+ @context.klass.ancestors
147
+ .select { |ancestor| ancestor.respond_to?(:model_name) }
148
+ .map { |ancestor| translated_attribute(ancestor) }
149
+ end
151
150
 
152
- def self.i18n_key(klass)
153
- raise "not implemented"
151
+ def i18n_key(klass)
152
+ raise "not implemented"
153
+ end
154
154
  end
155
155
  end
156
156
  end