ransack 1.7.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/SECURITY.md +12 -0
  4. data/.github/workflows/test.yml +120 -0
  5. data/.gitignore +3 -0
  6. data/CHANGELOG.md +463 -27
  7. data/CONTRIBUTING.md +52 -22
  8. data/Gemfile +24 -24
  9. data/README.md +453 -126
  10. data/Rakefile +6 -25
  11. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
  12. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
  13. data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
  14. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
  15. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
  16. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
  17. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
  18. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
  19. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
  20. data/lib/polyamorous/join.rb +70 -0
  21. data/lib/polyamorous/polyamorous.rb +24 -0
  22. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  23. data/lib/polyamorous/tree_node.rb +7 -0
  24. data/lib/ransack/adapters/active_record/base.rb +27 -2
  25. data/lib/ransack/adapters/active_record/context.rb +213 -139
  26. data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
  27. data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
  28. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
  29. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
  30. data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
  31. data/lib/ransack/adapters/active_record.rb +11 -10
  32. data/lib/ransack/adapters.rb +45 -23
  33. data/lib/ransack/configuration.rb +107 -4
  34. data/lib/ransack/constants.rb +13 -26
  35. data/lib/ransack/context.rb +45 -33
  36. data/lib/ransack/helpers/form_builder.rb +21 -12
  37. data/lib/ransack/helpers/form_helper.rb +75 -70
  38. data/lib/ransack/locale/ar.yml +70 -0
  39. data/lib/ransack/locale/az.yml +70 -0
  40. data/lib/ransack/locale/bg.yml +70 -0
  41. data/lib/ransack/locale/ca.yml +70 -0
  42. data/lib/ransack/locale/da.yml +70 -0
  43. data/lib/ransack/locale/el.yml +70 -0
  44. data/lib/ransack/locale/es.yml +22 -22
  45. data/lib/ransack/locale/fa.yml +70 -0
  46. data/lib/ransack/locale/fi.yml +71 -0
  47. data/lib/ransack/locale/id.yml +70 -0
  48. data/lib/ransack/locale/it.yml +70 -0
  49. data/lib/ransack/locale/ja.yml +70 -0
  50. data/lib/ransack/locale/nl.yml +4 -4
  51. data/lib/ransack/locale/pt-BR.yml +70 -0
  52. data/lib/ransack/locale/ru.yml +70 -0
  53. data/lib/ransack/locale/sk.yml +70 -0
  54. data/lib/ransack/locale/tr.yml +70 -0
  55. data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
  56. data/lib/ransack/locale/zh-TW.yml +70 -0
  57. data/lib/ransack/nodes/attribute.rb +5 -2
  58. data/lib/ransack/nodes/bindable.rb +18 -6
  59. data/lib/ransack/nodes/condition.rb +85 -28
  60. data/lib/ransack/nodes/grouping.rb +17 -11
  61. data/lib/ransack/nodes/sort.rb +9 -5
  62. data/lib/ransack/nodes/value.rb +74 -68
  63. data/lib/ransack/nodes.rb +1 -1
  64. data/lib/ransack/predicate.rb +17 -20
  65. data/lib/ransack/search.rb +17 -8
  66. data/lib/ransack/translate.rb +115 -115
  67. data/lib/ransack/version.rb +1 -1
  68. data/lib/ransack/visitor.rb +1 -12
  69. data/lib/ransack.rb +9 -9
  70. data/logo/ransack-h.png +0 -0
  71. data/logo/ransack-h.svg +34 -0
  72. data/logo/ransack-v.png +0 -0
  73. data/logo/ransack-v.svg +34 -0
  74. data/logo/ransack.png +0 -0
  75. data/logo/ransack.svg +21 -0
  76. data/ransack.gemspec +7 -24
  77. data/spec/console.rb +4 -0
  78. data/spec/helpers/polyamorous_helper.rb +19 -0
  79. data/spec/polyamorous/join_association_spec.rb +35 -0
  80. data/spec/polyamorous/join_dependency_spec.rb +97 -0
  81. data/spec/polyamorous/join_spec.rb +19 -0
  82. data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
  83. data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
  84. data/spec/ransack/configuration_spec.rb +97 -14
  85. data/spec/ransack/helpers/form_builder_spec.rb +2 -11
  86. data/spec/ransack/helpers/form_helper_spec.rb +481 -113
  87. data/spec/ransack/nodes/condition_spec.rb +24 -0
  88. data/spec/ransack/nodes/grouping_spec.rb +56 -0
  89. data/spec/ransack/predicate_spec.rb +79 -5
  90. data/spec/ransack/search_spec.rb +207 -81
  91. data/spec/spec_helper.rb +8 -0
  92. data/spec/support/schema.rb +100 -42
  93. metadata +57 -184
  94. data/.travis.yml +0 -69
  95. data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
  96. data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
  97. data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
  98. data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
  99. data/lib/ransack/adapters/active_record/compat.rb +0 -14
  100. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  101. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
  102. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
  103. data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
  104. data/lib/ransack/adapters/mongoid/base.rb +0 -130
  105. data/lib/ransack/adapters/mongoid/context.rb +0 -208
  106. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
  107. data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
  108. data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
  109. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
  110. data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
  111. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
  112. data/lib/ransack/adapters/mongoid/table.rb +0 -35
  113. data/lib/ransack/adapters/mongoid.rb +0 -13
  114. data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
  115. data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
  116. data/spec/mongoid/configuration_spec.rb +0 -102
  117. data/spec/mongoid/dependencies_spec.rb +0 -8
  118. data/spec/mongoid/helpers/ransack_helper.rb +0 -11
  119. data/spec/mongoid/nodes/condition_spec.rb +0 -34
  120. data/spec/mongoid/nodes/grouping_spec.rb +0 -13
  121. data/spec/mongoid/predicate_spec.rb +0 -155
  122. data/spec/mongoid/search_spec.rb +0 -446
  123. data/spec/mongoid/support/mongoid.yml +0 -6
  124. data/spec/mongoid/support/schema.rb +0 -128
  125. data/spec/mongoid/translate_spec.rb +0 -14
  126. data/spec/mongoid_spec_helper.rb +0 -59
  127. data/spec/ransack/dependencies_spec.rb +0 -12
@@ -23,87 +23,93 @@ module Ransack
23
23
  end
24
24
 
25
25
  def cast(type)
26
- case type
27
- when :date
28
- cast_to_date(value)
29
- when :datetime, :timestamp, :time
30
- cast_to_time(value)
31
- when :boolean
32
- cast_to_boolean(value)
33
- when :integer
34
- cast_to_integer(value)
35
- when :float
36
- cast_to_float(value)
37
- when :decimal
38
- cast_to_decimal(value)
39
- else
40
- cast_to_string(value)
41
- end
42
- end
26
+ case type
27
+ when :date
28
+ cast_to_date(value)
29
+ when :datetime, :timestamp, :time
30
+ cast_to_time(value)
31
+ when :boolean
32
+ cast_to_boolean(value)
33
+ when :integer
34
+ cast_to_integer(value)
35
+ when :float
36
+ cast_to_float(value)
37
+ when :decimal
38
+ cast_to_decimal(value)
39
+ when :money
40
+ cast_to_money(value)
41
+ else
42
+ cast_to_string(value)
43
+ end
44
+ end
43
45
 
44
- def cast_to_date(val)
45
- if val.respond_to?(:to_date)
46
- val.to_date rescue nil
47
- else
48
- y, m, d = *[val].flatten
49
- m ||= 1
50
- d ||= 1
51
- Date.new(y,m,d) rescue nil
52
- end
53
- end
46
+ def cast_to_date(val)
47
+ if val.respond_to?(:to_date)
48
+ val.to_date rescue nil
49
+ else
50
+ y, m, d = *[val].flatten
51
+ m ||= 1
52
+ d ||= 1
53
+ Date.new(y,m,d) rescue nil
54
+ end
55
+ end
54
56
 
55
- def cast_to_time(val)
56
- if val.is_a?(Array)
57
- Time.zone.local(*val) rescue nil
58
- else
59
- unless val.acts_like?(:time)
60
- val = val.is_a?(String) ? Time.zone.parse(val) : val.to_time rescue val
61
- end
62
- val.in_time_zone rescue nil
63
- end
64
- end
57
+ def cast_to_time(val)
58
+ if val.is_a?(Array)
59
+ Time.zone.local(*val) rescue nil
60
+ else
61
+ unless val.acts_like?(:time)
62
+ val = val.is_a?(String) ? Time.zone.parse(val) : val.to_time rescue val
63
+ end
64
+ val.in_time_zone rescue nil
65
+ end
66
+ end
65
67
 
66
- def cast_to_boolean(val)
67
- if Constants::TRUE_VALUES.include?(val)
68
- true
69
- elsif Constants::FALSE_VALUES.include?(val)
70
- false
71
- else
72
- nil
73
- end
74
- end
68
+ def cast_to_boolean(val)
69
+ if Constants::TRUE_VALUES.include?(val)
70
+ true
71
+ elsif Constants::FALSE_VALUES.include?(val)
72
+ false
73
+ else
74
+ nil
75
+ end
76
+ end
75
77
 
76
- def cast_to_string(val)
77
- val.respond_to?(:to_s) ? val.to_s : String.new(val)
78
- end
78
+ def cast_to_string(val)
79
+ val.respond_to?(:to_s) ? val.to_s : String.new(val)
80
+ end
79
81
 
80
- def cast_to_integer(val)
81
- val.blank? ? nil : val.to_i
82
- end
82
+ def cast_to_integer(val)
83
+ val.blank? ? nil : val.to_i
84
+ end
83
85
 
84
- def cast_to_float(val)
85
- val.blank? ? nil : val.to_f
86
- end
86
+ def cast_to_float(val)
87
+ val.blank? ? nil : val.to_f
88
+ end
87
89
 
88
- def cast_to_decimal(val)
89
- if val.blank?
90
- nil
91
- elsif val.class == BigDecimal
92
- val
93
- elsif val.respond_to?(:to_d)
94
- val.to_d
95
- else
96
- val.to_s.to_d
97
- end
90
+ def cast_to_decimal(val)
91
+ if val.blank?
92
+ nil
93
+ elsif val.class == BigDecimal
94
+ val
95
+ elsif val.respond_to?(:to_d)
96
+ val.to_d
97
+ else
98
+ val.to_s.to_d
98
99
  end
100
+ end
101
+
102
+ def cast_to_money(val)
103
+ val.blank? ? nil : val.to_f.to_s
104
+ end
99
105
 
100
106
  def inspect
101
107
  "Value <#{value}>"
102
108
  end
103
109
 
104
- def array_of_arrays?(val)
105
- Array === val && Array === val.first
106
- end
110
+ def array_of_arrays?(val)
111
+ Array === val && Array === val.first
112
+ end
107
113
  end
108
114
  end
109
115
  end
data/lib/ransack/nodes.rb CHANGED
@@ -3,6 +3,6 @@ require 'ransack/nodes/node'
3
3
  require 'ransack/nodes/attribute'
4
4
  require 'ransack/nodes/value'
5
5
  require 'ransack/nodes/condition'
6
- Ransack::Adapters.require_nodes
6
+ Ransack::Adapters.object_mapper.require_nodes
7
7
  require 'ransack/nodes/sort'
8
8
  require 'ransack/nodes/grouping'
@@ -1,7 +1,7 @@
1
1
  module Ransack
2
2
  class Predicate
3
3
  attr_reader :name, :arel_predicate, :type, :formatter, :validator,
4
- :compound, :wants_array
4
+ :compound, :wants_array, :case_insensitive
5
5
 
6
6
  class << self
7
7
 
@@ -9,34 +9,26 @@ module Ransack
9
9
  Ransack.predicates.keys
10
10
  end
11
11
 
12
- def names_by_decreasing_length
13
- names.sort { |a,b| b.length <=> a.length }
14
- end
15
-
16
12
  def named(name)
17
13
  Ransack.predicates[name.to_s]
18
14
  end
19
15
 
20
16
  def detect_and_strip_from_string!(str)
21
- if p = detect_from_string(str)
22
- str.sub! /_#{p}$/, Constants::EMPTY
23
- p
24
- end
17
+ detect_from_string str, chomp: true
25
18
  end
26
19
 
27
- def detect_from_string(str)
28
- names_by_decreasing_length.detect { |p| str.end_with?("_#{p}") }
29
- end
20
+ def detect_from_string(str, chomp: false)
21
+ return unless str
30
22
 
31
- # def name_from_attribute_name(attribute_name)
32
- # names_by_decreasing_length.detect {
33
- # |p| attribute_name.to_s.match(/_#{p}$/)
34
- # }
35
- # end
23
+ Ransack.predicates.sorted_names_with_underscores.each do |predicate, underscored|
24
+ if str.end_with? underscored
25
+ str.chomp! underscored if chomp
26
+ return predicate
27
+ end
28
+ end
36
29
 
37
- # def for_attribute_name(attribute_name)
38
- # self.named(detect_from_string(attribute_name.to_s))
39
- # end
30
+ nil
31
+ end
40
32
 
41
33
  end
42
34
 
@@ -50,6 +42,7 @@ module Ransack
50
42
  @compound = opts[:compound]
51
43
  @wants_array = opts.fetch(:wants_array,
52
44
  @compound || Constants::IN_NOT_IN.include?(@arel_predicate))
45
+ @case_insensitive = opts[:case_insensitive]
53
46
  end
54
47
 
55
48
  def eql?(other)
@@ -74,5 +67,9 @@ module Ransack
74
67
  vals.any? { |v| validator.call(type ? v.cast(type) : v.value) }
75
68
  end
76
69
 
70
+ def negative?
71
+ @name.include?("not_".freeze)
72
+ end
73
+
77
74
  end
78
75
  end
@@ -1,6 +1,6 @@
1
1
  require 'ransack/nodes'
2
2
  require 'ransack/context'
3
- Ransack::Adapters.require_search
3
+ Ransack::Adapters.object_mapper.require_search
4
4
  require 'ransack/naming'
5
5
 
6
6
  module Ransack
@@ -15,8 +15,10 @@ module Ransack
15
15
  :translate, :to => :base
16
16
 
17
17
  def initialize(object, params = {}, options = {})
18
+ params = params.to_unsafe_h if params.respond_to?(:to_unsafe_h)
18
19
  if params.is_a? Hash
19
20
  params = params.dup
21
+ params = params.transform_values { |v| v.is_a?(String) ? v.strip : v }
20
22
  params.delete_if { |k, v| [*v].all?{ |i| i.blank? && i != false } }
21
23
  else
22
24
  params = {}
@@ -28,6 +30,7 @@ module Ransack
28
30
  )
29
31
  @scope_args = {}
30
32
  @sorts ||= []
33
+ @ignore_unknown_conditions = options[:ignore_unknown_conditions] == false ? false : true
31
34
  build(params.with_indifferent_access)
32
35
  end
33
36
 
@@ -37,13 +40,13 @@ module Ransack
37
40
 
38
41
  def build(params)
39
42
  collapse_multiparameter_attributes!(params).each do |key, value|
40
- if Constants::S_SORTS.include?(key)
43
+ if ['s'.freeze, 'sorts'.freeze].freeze.include?(key)
41
44
  send("#{key}=", value)
42
45
  elsif base.attribute_method?(key)
43
46
  base.send("#{key}=", value)
44
47
  elsif @context.ransackable_scope?(key, @context.object)
45
48
  add_scope(key, value)
46
- elsif !Ransack.options[:ignore_unknown_conditions]
49
+ elsif !Ransack.options[:ignore_unknown_conditions] || !@ignore_unknown_conditions
47
50
  raise ArgumentError, "Invalid search term #{key}"
48
51
  end
49
52
  end
@@ -92,7 +95,7 @@ module Ransack
92
95
 
93
96
  def method_missing(method_id, *args)
94
97
  method_name = method_id.to_s
95
- getter_name = method_name.sub(/=$/, Constants::EMPTY)
98
+ getter_name = method_name.sub(/=$/, ''.freeze)
96
99
  if base.attribute_method?(getter_name)
97
100
  base.send(method_id, *args)
98
101
  elsif @context.ransackable_scope?(getter_name, @context.object)
@@ -113,8 +116,8 @@ module Ransack
113
116
  [:base, base.inspect]
114
117
  ]
115
118
  .compact
116
- .map { |d| d.join(Constants::COLON_SPACE) }
117
- .join(Constants::COMMA_SPACE)
119
+ .map { |d| d.join(': '.freeze) }
120
+ .join(', '.freeze)
118
121
 
119
122
  "Ransack::Search<#{details}>"
120
123
  end
@@ -122,12 +125,18 @@ module Ransack
122
125
  private
123
126
 
124
127
  def add_scope(key, args)
128
+ sanitized_args = if Ransack.options[:sanitize_scope_args] && !@context.ransackable_scope_skip_sanitize_args?(key, @context.object)
129
+ sanitized_scope_args(args)
130
+ else
131
+ args
132
+ end
133
+
125
134
  if @context.scope_arity(key) == 1
126
135
  @scope_args[key] = args.is_a?(Array) ? args[0] : args
127
136
  else
128
- @scope_args[key] = args.is_a?(Array) ? sanitized_scope_args(args) : args
137
+ @scope_args[key] = args.is_a?(Array) ? sanitized_args : args
129
138
  end
130
- @context.chain_scope(key, sanitized_scope_args(args))
139
+ @context.chain_scope(key, sanitized_args)
131
140
  end
132
141
 
133
142
  def sanitized_scope_args(args)
@@ -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
- predicate = Predicate.detect_from_string(original_name)
28
- attributes_str = original_name.sub(/_#{predicate}$/, Constants::EMPTY)
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}_/, Constants::EMPTY)
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
@@ -1,3 +1,3 @@
1
1
  module Ransack
2
- VERSION = '1.7.0'
2
+ VERSION = '2.4.1'
3
3
  end
@@ -31,17 +31,7 @@ module Ransack
31
31
 
32
32
  def visit_or(object)
33
33
  nodes = object.values.map { |o| accept(o) }.compact
34
- return nil unless nodes.size > 0
35
-
36
- if nodes.size > 1
37
- nodes.inject(&:or)
38
- else
39
- nodes.first
40
- end
41
- end
42
-
43
- def visit_Ransack_Nodes_Sort(object)
44
- object.attr.send(object.dir) if object.valid?
34
+ nodes.inject(&:or)
45
35
  end
46
36
 
47
37
  def quoted?(object)
@@ -57,6 +47,5 @@ module Ransack
57
47
  klass.name.gsub(Constants::TWO_COLONS, Constants::UNDERSCORE)
58
48
  }"
59
49
  end
60
-
61
50
  end
62
51
  end
data/lib/ransack.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'active_support/core_ext'
2
-
3
2
  require 'ransack/configuration'
4
-
5
3
  require 'ransack/adapters'
6
- Ransack::Adapters.require_constants
4
+ require 'polyamorous/polyamorous.rb'
5
+
6
+ Ransack::Adapters.object_mapper.require_constants
7
7
 
8
8
  module Ransack
9
9
  extend Configuration
@@ -15,17 +15,17 @@ Ransack.configure do |config|
15
15
  config.add_predicate name, :arel_predicate => name
16
16
  end
17
17
  Ransack::Constants::DERIVED_PREDICATES.each do |args|
18
- config.add_predicate *args
18
+ config.add_predicate(*args)
19
19
  end
20
20
  end
21
21
 
22
22
  require 'ransack/search'
23
23
  require 'ransack/ransacker'
24
- require 'ransack/helpers'
25
- require 'action_controller'
26
-
27
24
  require 'ransack/translate'
28
25
 
29
- Ransack::Adapters.require_adapter
26
+ Ransack::Adapters.object_mapper.require_adapter
30
27
 
31
- ActionController::Base.helper Ransack::Helpers::FormHelper
28
+ ActiveSupport.on_load(:action_controller) do
29
+ require 'ransack/helpers'
30
+ ActionController::Base.helper Ransack::Helpers::FormHelper
31
+ end
Binary file