ransack 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +47 -3
  3. data/CHANGELOG.md +106 -18
  4. data/CONTRIBUTING.md +56 -23
  5. data/Gemfile +16 -5
  6. data/README.md +114 -38
  7. data/Rakefile +30 -2
  8. data/lib/ransack.rb +9 -0
  9. data/lib/ransack/adapters/active_record/3.0/compat.rb +11 -8
  10. data/lib/ransack/adapters/active_record/3.0/context.rb +14 -22
  11. data/lib/ransack/adapters/active_record/3.1/context.rb +14 -22
  12. data/lib/ransack/adapters/active_record/context.rb +36 -31
  13. data/lib/ransack/adapters/active_record/ransack/constants.rb +113 -0
  14. data/lib/ransack/adapters/active_record/ransack/context.rb +64 -0
  15. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +48 -0
  16. data/lib/ransack/adapters/active_record/ransack/translate.rb +12 -0
  17. data/lib/ransack/adapters/active_record/ransack/visitor.rb +24 -0
  18. data/lib/ransack/adapters/mongoid.rb +13 -0
  19. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  20. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +37 -0
  21. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +17 -0
  22. data/lib/ransack/adapters/mongoid/attributes/predications.rb +141 -0
  23. data/lib/ransack/adapters/mongoid/base.rb +126 -0
  24. data/lib/ransack/adapters/mongoid/context.rb +208 -0
  25. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +23 -0
  26. data/lib/ransack/adapters/mongoid/ransack/constants.rb +88 -0
  27. data/lib/ransack/adapters/mongoid/ransack/context.rb +60 -0
  28. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +27 -0
  29. data/lib/ransack/adapters/mongoid/ransack/translate.rb +13 -0
  30. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +24 -0
  31. data/lib/ransack/adapters/mongoid/table.rb +35 -0
  32. data/lib/ransack/configuration.rb +22 -4
  33. data/lib/ransack/constants.rb +26 -120
  34. data/lib/ransack/context.rb +32 -60
  35. data/lib/ransack/helpers/form_builder.rb +50 -36
  36. data/lib/ransack/helpers/form_helper.rb +148 -104
  37. data/lib/ransack/naming.rb +11 -11
  38. data/lib/ransack/nodes.rb +2 -0
  39. data/lib/ransack/nodes/bindable.rb +12 -4
  40. data/lib/ransack/nodes/condition.rb +5 -22
  41. data/lib/ransack/nodes/grouping.rb +9 -10
  42. data/lib/ransack/nodes/sort.rb +3 -2
  43. data/lib/ransack/nodes/value.rb +1 -2
  44. data/lib/ransack/predicate.rb +3 -3
  45. data/lib/ransack/search.rb +46 -13
  46. data/lib/ransack/translate.rb +8 -8
  47. data/lib/ransack/version.rb +1 -1
  48. data/lib/ransack/visitor.rb +4 -16
  49. data/ransack.gemspec +1 -0
  50. data/spec/mongoid/adapters/mongoid/base_spec.rb +276 -0
  51. data/spec/mongoid/adapters/mongoid/context_spec.rb +56 -0
  52. data/spec/mongoid/configuration_spec.rb +66 -0
  53. data/spec/mongoid/dependencies_spec.rb +8 -0
  54. data/spec/mongoid/helpers/ransack_helper.rb +11 -0
  55. data/spec/mongoid/nodes/condition_spec.rb +34 -0
  56. data/spec/mongoid/nodes/grouping_spec.rb +13 -0
  57. data/spec/mongoid/predicate_spec.rb +155 -0
  58. data/spec/mongoid/search_spec.rb +446 -0
  59. data/spec/mongoid/support/mongoid.yml +6 -0
  60. data/spec/mongoid/support/schema.rb +128 -0
  61. data/spec/mongoid/translate_spec.rb +14 -0
  62. data/spec/mongoid_spec_helper.rb +59 -0
  63. data/spec/ransack/adapters/active_record/base_spec.rb +68 -35
  64. data/spec/ransack/dependencies_spec.rb +3 -1
  65. data/spec/ransack/helpers/form_builder_spec.rb +6 -6
  66. data/spec/ransack/helpers/form_helper_spec.rb +114 -47
  67. data/spec/ransack/nodes/condition_spec.rb +2 -2
  68. data/spec/ransack/search_spec.rb +2 -6
  69. data/spec/ransack/translate_spec.rb +1 -1
  70. data/spec/spec_helper.rb +2 -3
  71. data/spec/support/schema.rb +9 -0
  72. metadata +49 -4
@@ -0,0 +1,35 @@
1
+ module Ransack
2
+ module Adapters
3
+ module Mongoid
4
+ class Table
5
+ attr_accessor :name
6
+
7
+ alias :table_name :name
8
+
9
+ def initialize(object, engine = nil)
10
+ @object = object
11
+ @name = object.collection.name
12
+ @engine = engine
13
+ @columns = nil
14
+ @aliases = []
15
+ @table_alias = nil
16
+ @primary_key = nil
17
+
18
+ if Hash === engine
19
+ # @engine = engine[:engine] || Table.engine
20
+
21
+ # Sometime AR sends an :as parameter to table, to let the table know
22
+ # that it is an Alias. We may want to override new, and return a
23
+ # TableAlias node?
24
+ # @table_alias = engine[:as] unless engine[:as].to_s == @name
25
+ end
26
+ end
27
+
28
+ def [](name)
29
+ Ransack::Adapters::Mongoid::Attribute.new self, name
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -24,7 +24,7 @@ module Ransack
24
24
 
25
25
  self.predicates[name] = Predicate.new(opts)
26
26
 
27
- Ransack::Constants::SUFFIXES.each do |suffix|
27
+ Constants::SUFFIXES.each do |suffix|
28
28
  compound_name = name + suffix
29
29
  self.predicates[compound_name] = Predicate.new(
30
30
  opts.merge(
@@ -38,13 +38,31 @@ module Ransack
38
38
  end if compounds
39
39
  end
40
40
 
41
- # default search_key that, it can be overridden on sort_link level
41
+ # The default `search_key` name is `:q`. The default key may be overridden
42
+ # in an initializer file like `config/initializers/ransack.rb` as follows:
43
+ #
44
+ # Ransack.configure do |config|
45
+ # # Name the search_key `:query` instead of the default `:q`
46
+ # config.search_key = :query
47
+ # end
48
+ #
49
+ # Sometimes there are situations when the default search parameter name
50
+ # cannot be used, for instance if there were two searches on one page.
51
+ # Another name can be set using the `search_key` option with Ransack
52
+ # `ransack`, `search` and `@search_form_for` methods in controllers & views.
53
+ #
54
+ # In the controller:
55
+ # @search = Log.ransack(params[:log_search], search_key: :log_search)
56
+ #
57
+ # In the view:
58
+ # <%= f.search_form_for @search, as: :log_search %>
59
+ #
42
60
  def search_key=(name)
43
61
  self.options[:search_key] = name
44
62
  end
45
63
 
46
- # raise an error if an unknown predicate, condition or attribute is passed
47
- # into a search
64
+ # Raise an error if an unknown predicate, condition or attribute is passed
65
+ # into a search.
48
66
  def ignore_unknown_conditions=(boolean)
49
67
  self.options[:ignore_unknown_conditions] = boolean
50
68
  end
@@ -2,22 +2,39 @@ module Ransack
2
2
  module Constants
3
3
  ASC = 'asc'.freeze
4
4
  DESC = 'desc'.freeze
5
+ ASC_DESC = [ASC, DESC].freeze
6
+
5
7
  ASC_ARROW = '&#9650;'.freeze
6
8
  DESC_ARROW = '&#9660;'.freeze
9
+
7
10
  OR = 'or'.freeze
8
11
  AND = 'and'.freeze
12
+ SPACED_AND = ' AND '.freeze
13
+
9
14
  SORT = 'sort'.freeze
10
15
  SORT_LINK = 'sort_link'.freeze
16
+ SORT_DIRECTION = 'sort_direction'.freeze
17
+
18
+ CAP_SEARCH = 'Search'.freeze
11
19
  SEARCH = 'search'.freeze
12
- DEFAULT_SEARCH_KEY = 'q'.freeze
20
+ SEARCHES = 'searches'.freeze
21
+
13
22
  ATTRIBUTE = 'attribute'.freeze
14
- DISTINCT = 'DISTINCT '.freeze
23
+ ATTRIBUTES = 'attributes'.freeze
15
24
  COMBINATOR = 'combinator'.freeze
25
+
16
26
  SPACE = ' '.freeze
17
27
  COMMA_SPACE = ', '.freeze
28
+ COLON_SPACE = ': '.freeze
29
+ TWO_COLONS = '::'.freeze
18
30
  UNDERSCORE = '_'.freeze
31
+ LEFT_PARENTHESIS = '('.freeze
32
+ Q = 'q'.freeze
33
+ I = 'i'.freeze
19
34
  NON_BREAKING_SPACE = '&nbsp;'.freeze
35
+ DOT_ASTERIX = '.*'.freeze
20
36
  EMPTY = ''.freeze
37
+
21
38
  STRING_JOIN = 'string_join'.freeze
22
39
  ASSOCIATION_JOIN = 'association_join'.freeze
23
40
  STASHED_JOIN = 'stashed_join'.freeze
@@ -25,138 +42,27 @@ module Ransack
25
42
 
26
43
  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
27
44
  FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
28
- BOOLEAN_VALUES = TRUE_VALUES + FALSE_VALUES
45
+ BOOLEAN_VALUES = (TRUE_VALUES + FALSE_VALUES).freeze
29
46
 
30
47
  S_SORTS = %w(s sorts).freeze
31
- ASC_DESC = %w(asc desc).freeze
32
48
  AND_OR = %w(and or).freeze
33
49
  IN_NOT_IN = %w(in not_in).freeze
34
50
  SUFFIXES = %w(_any _all).freeze
35
51
  AREL_PREDICATES = %w(
36
52
  eq not_eq matches does_not_match lt lteq gt gteq in not_in
37
53
  ).freeze
54
+ A_S_I = %w(a s i).freeze
38
55
 
39
56
  EQ = 'eq'.freeze
40
57
  NOT_EQ = 'not_eq'.freeze
41
58
  EQ_ANY = 'eq_any'.freeze
42
59
  NOT_EQ_ALL = 'not_eq_all'.freeze
60
+ CONT = 'cont'.freeze
43
61
 
44
- DERIVED_PREDICATES = [
45
- ['cont'.freeze, {
46
- :arel_predicate => 'matches'.freeze,
47
- :formatter => proc { |v| "%#{escape_wildcards(v)}%" }
48
- }
49
- ],
50
- ['i_cont'.freeze, {
51
- :arel_predicate => 'i_matches'.freeze,
52
- :formatter => proc { |v| "%#{escape_wildcards(v)}%" }
53
- }
54
- ],
55
- ['not_cont'.freeze, {
56
- :arel_predicate => 'does_not_match'.freeze,
57
- :formatter => proc { |v| "%#{escape_wildcards(v)}%" }
58
- }
59
- ],
60
- ['i_not_cont'.freeze, {
61
- :arel_predicate => 'i_does_not_match'.freeze,
62
- :formatter => proc { |v| "%#{escape_wildcards(v)}%" }
63
- }
64
- ],
65
- ['start'.freeze, {
66
- :arel_predicate => 'matches'.freeze,
67
- :formatter => proc { |v| "#{escape_wildcards(v)}%" }
68
- }
69
- ],
70
- ['not_start'.freeze, {
71
- :arel_predicate => 'does_not_match'.freeze,
72
- :formatter => proc { |v| "#{escape_wildcards(v)}%" }
73
- }
74
- ],
75
- ['end'.freeze, {
76
- :arel_predicate => 'matches'.freeze,
77
- :formatter => proc { |v| "%#{escape_wildcards(v)}" }
78
- }
79
- ],
80
- ['not_end'.freeze, {
81
- :arel_predicate => 'does_not_match'.freeze,
82
- :formatter => proc { |v| "%#{escape_wildcards(v)}" }
83
- }
84
- ],
85
- ['true'.freeze, {
86
- :arel_predicate => proc { |v| v ? EQ : NOT_EQ },
87
- :compounds => false,
88
- :type => :boolean,
89
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
90
- :formatter => proc { |v| true }
91
- }
92
- ],
93
- ['not_true'.freeze, {
94
- :arel_predicate => proc { |v| v ? NOT_EQ : EQ },
95
- :compounds => false,
96
- :type => :boolean,
97
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
98
- :formatter => proc { |v| true }
99
- }
100
- ],
101
- ['false'.freeze, {
102
- :arel_predicate => proc { |v| v ? EQ : NOT_EQ },
103
- :compounds => false,
104
- :type => :boolean,
105
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
106
- :formatter => proc { |v| false }
107
- }
108
- ],
109
- ['not_false'.freeze, {
110
- :arel_predicate => proc { |v| v ? NOT_EQ : EQ },
111
- :compounds => false,
112
- :type => :boolean,
113
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
114
- :formatter => proc { |v| false }
115
- }
116
- ],
117
- ['present'.freeze, {
118
- :arel_predicate => proc { |v| v ? NOT_EQ_ALL : EQ_ANY },
119
- :compounds => false,
120
- :type => :boolean,
121
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
122
- :formatter => proc { |v| [nil, Ransack::Constants::EMPTY] }
123
- }
124
- ],
125
- ['blank'.freeze, {
126
- :arel_predicate => proc { |v| v ? EQ_ANY : NOT_EQ_ALL },
127
- :compounds => false,
128
- :type => :boolean,
129
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
130
- :formatter => proc { |v| [nil, Ransack::Constants::EMPTY] }
131
- }
132
- ],
133
- ['null'.freeze, {
134
- :arel_predicate => proc { |v| v ? EQ : NOT_EQ },
135
- :compounds => false,
136
- :type => :boolean,
137
- :validator => proc { |v| BOOLEAN_VALUES.include?(v)},
138
- :formatter => proc { |v| nil }
139
- }
140
- ],
141
- ['not_null'.freeze, {
142
- :arel_predicate => proc { |v| v ? NOT_EQ : EQ },
143
- :compounds => false,
144
- :type => :boolean,
145
- :validator => proc { |v| BOOLEAN_VALUES.include?(v) },
146
- :formatter => proc { |v| nil } }
147
- ]
148
- ].freeze
62
+ RAILS_4_1 = '4.1'.freeze
149
63
 
150
- module_function
151
- # replace % \ to \% \\
152
- def escape_wildcards(unescaped)
153
- case ActiveRecord::Base.connection.adapter_name
154
- when "Mysql2".freeze, "PostgreSQL".freeze
155
- # Necessary for PostgreSQL and MySQL
156
- unescaped.to_s.gsub(/([\\|\%|.])/, '\\\\\\1')
157
- else
158
- unescaped
159
- end
160
- end
64
+ RANSACK_SLASH_SEARCHES = 'ransack/searches'.freeze
65
+ RANSACK_SLASH_SEARCHES_SLASH_SEARCH = 'ransack/searches/search'.freeze
161
66
  end
162
67
  end
68
+
@@ -1,12 +1,28 @@
1
1
  require 'ransack/visitor'
2
2
 
3
+ if defined?(::ActiveRecord::Base)
4
+ require 'ransack/adapters/active_record/ransack/visitor'
5
+ end
6
+
7
+ if defined?(::Mongoid)
8
+ require 'ransack/adapters/mongoid/ransack/visitor'
9
+ end
10
+
3
11
  module Ransack
4
12
  class Context
5
- attr_reader :object, :klass, :base, :engine, :arel_visitor
13
+ attr_reader :search, :object, :klass, :base, :engine, :arel_visitor
6
14
  attr_accessor :auth_object, :search_key
7
15
 
8
16
  class << self
9
17
 
18
+ def for_class(klass, options = {})
19
+ raise "not implemented"
20
+ end
21
+
22
+ def for_object(object, options = {})
23
+ raise "not implemented"
24
+ end
25
+
10
26
  def for(object, options = {})
11
27
  context = Class === object ?
12
28
  for_class(object, options) :
@@ -15,59 +31,14 @@ module Ransack
15
31
  "Don't know what context to use for #{object}"
16
32
  end
17
33
 
18
- def for_class(klass, options = {})
19
- if klass < ActiveRecord::Base
20
- Adapters::ActiveRecord::Context.new(klass, options)
21
- end
22
- end
23
-
24
- def for_object(object, options = {})
25
- case object
26
- when ActiveRecord::Relation
27
- Adapters::ActiveRecord::Context.new(object.klass, options)
28
- end
29
- end
30
-
31
- end
34
+ end # << self
32
35
 
33
36
  def initialize(object, options = {})
34
- @object = relation_for(object)
35
- @klass = @object.klass
36
- @join_dependency = join_dependency(@object)
37
- @join_type = options[:join_type] || Polyamorous::OuterJoin
38
- @search_key = options[:search_key] || Ransack.options[:search_key]
39
-
40
- if ::ActiveRecord::VERSION::STRING >= "4.1".freeze
41
- @base = @join_dependency.join_root
42
- @engine = @base.base_klass.arel_engine
43
- else
44
- @base = @join_dependency.join_base
45
- @engine = @base.arel_engine
46
- end
47
-
48
- @default_table = Arel::Table.new(
49
- @base.table_name, :as => @base.aliased_table_name, :engine => @engine
50
- )
51
- @bind_pairs = Hash.new do |hash, key|
52
- parent, attr_name = get_parent_and_attribute_name(key.to_s)
53
- if parent && attr_name
54
- hash[key] = [parent, attr_name]
55
- end
56
- end
37
+ raise "not implemented"
57
38
  end
58
39
 
59
40
  def klassify(obj)
60
- if Class === obj && ::ActiveRecord::Base > obj
61
- obj
62
- elsif obj.respond_to? :klass
63
- obj.klass
64
- elsif obj.respond_to? :active_record # Rails 3
65
- obj.active_record
66
- elsif obj.respond_to? :base_klass # Rails 4
67
- obj.base_klass
68
- else
69
- raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
70
- end
41
+ raise "not implemented"
71
42
  end
72
43
 
73
44
  # Convert a string representing a chain of associations and an attribute
@@ -95,7 +66,7 @@ module Ransack
95
66
  end
96
67
 
97
68
  def traverse(str, base = @base)
98
- str ||= Ransack::Constants::EMPTY
69
+ str ||= Constants::EMPTY
99
70
 
100
71
  if (segments = str.split(/_/)).size > 0
101
72
  remainder = []
@@ -103,12 +74,13 @@ module Ransack
103
74
  while !found_assoc && segments.size > 0 do
104
75
  # Strip the _of_Model_type text from the association name, but hold
105
76
  # onto it in klass, for use as the next base
106
- assoc, klass = unpolymorphize_association(segments
107
- .join(Ransack::Constants::UNDERSCORE))
77
+ assoc, klass = unpolymorphize_association(
78
+ segments.join(Constants::UNDERSCORE)
79
+ )
108
80
  if found_assoc = get_association(assoc, base)
109
81
  base = traverse(
110
82
  remainder.join(
111
- Ransack::Constants::UNDERSCORE), klass || found_assoc.klass
83
+ Constants::UNDERSCORE), klass || found_assoc.klass
112
84
  )
113
85
  end
114
86
 
@@ -123,16 +95,16 @@ module Ransack
123
95
 
124
96
  def association_path(str, base = @base)
125
97
  base = klassify(base)
126
- str ||= Ransack::Constants::EMPTY
98
+ str ||= Constants::EMPTY
127
99
  path = []
128
100
  segments = str.split(/_/)
129
101
  association_parts = []
130
102
  if (segments = str.split(/_/)).size > 0
131
103
  while segments.size > 0 &&
132
- !base.columns_hash[segments.join(Ransack::Constants::UNDERSCORE)] &&
104
+ !base.columns_hash[segments.join(Constants::UNDERSCORE)] &&
133
105
  association_parts << segments.shift do
134
106
  assoc, klass = unpolymorphize_association(
135
- association_parts.join(Ransack::Constants::UNDERSCORE)
107
+ association_parts.join(Constants::UNDERSCORE)
136
108
  )
137
109
  if found_assoc = get_association(assoc, base)
138
110
  path += association_parts
@@ -142,7 +114,7 @@ module Ransack
142
114
  end
143
115
  end
144
116
 
145
- path.join(Ransack::Constants::UNDERSCORE)
117
+ path.join(Constants::UNDERSCORE)
146
118
  end
147
119
 
148
120
  def unpolymorphize_association(str)
@@ -166,15 +138,15 @@ module Ransack
166
138
  klass.ransackable_scopes(auth_object).any? { |s| s.to_s == str }
167
139
  end
168
140
 
169
- def searchable_attributes(str = Ransack::Constants::EMPTY)
141
+ def searchable_attributes(str = Constants::EMPTY)
170
142
  traverse(str).ransackable_attributes(auth_object)
171
143
  end
172
144
 
173
- def sortable_attributes(str = Ransack::Constants::EMPTY)
145
+ def sortable_attributes(str = Constants::EMPTY)
174
146
  traverse(str).ransortable_attributes(auth_object)
175
147
  end
176
148
 
177
- def searchable_associations(str = Ransack::Constants::EMPTY)
149
+ def searchable_associations(str = Constants::EMPTY)
178
150
  traverse(str).ransackable_associations(auth_object)
179
151
  end
180
152
  end
@@ -1,5 +1,19 @@
1
1
  require 'action_view'
2
2
 
3
+ # This patch is needed since this Rails commit:
4
+ # https://github.com/rails/rails/commit/c1a118a
5
+ #
6
+ # TODO: Find a better way to solve this.
7
+ #
8
+ module ActionView::Helpers::Tags
9
+ class Base
10
+ private
11
+ def value(object)
12
+ object.send @method_name if object # use send instead of public_send
13
+ end
14
+ end
15
+ end
16
+
3
17
  RANSACK_FORM_BUILDER = 'RANSACK_FORM_BUILDER'.freeze
4
18
 
5
19
  require 'simple_form' if
@@ -30,13 +44,12 @@ module Ransack
30
44
  def attribute_select(options = nil, html_options = nil, action = nil)
31
45
  options = options || {}
32
46
  html_options = html_options || {}
33
- action = action || Ransack::Constants::SEARCH
47
+ action = action || Constants::SEARCH
34
48
  default = options.delete(:default)
35
49
  raise ArgumentError, formbuilder_error_message(
36
50
  "#{action}_select") unless object.respond_to?(:context)
37
51
  options[:include_blank] = true unless options.has_key?(:include_blank)
38
- bases = [Ransack::Constants::EMPTY] +
39
- association_array(options[:associations])
52
+ bases = [Constants::EMPTY] + association_array(options[:associations])
40
53
  if bases.size > 1
41
54
  collection = attribute_collection_for_bases(action, bases)
42
55
  object.name ||= default if can_use_default?(
@@ -53,13 +66,15 @@ module Ransack
53
66
  end
54
67
 
55
68
  def sort_direction_select(options = {}, html_options = {})
56
- raise ArgumentError, formbuilder_error_message(
57
- 'sort_direction'.freeze) unless object.respond_to?(:context)
69
+ unless object.respond_to?(:context)
70
+ raise ArgumentError,
71
+ formbuilder_error_message(Constants::SORT_DIRECTION)
72
+ end
58
73
  template_collection_select(:dir, sort_array, options, html_options)
59
74
  end
60
75
 
61
76
  def sort_select(options = {}, html_options = {})
62
- attribute_select(options, html_options, Ransack::Constants::SORT) +
77
+ attribute_select(options, html_options, Constants::SORT) +
63
78
  sort_direction_select(options, html_options)
64
79
  end
65
80
 
@@ -100,35 +115,35 @@ module Ransack
100
115
  objects ||= @object.send(name)
101
116
  objects = [objects] unless Array === objects
102
117
  name = "#{options[:object_name] || object_name}[#{name}]"
103
- output = ActiveSupport::SafeBuffer.new
104
- objects.each do |child|
105
- output << @template.fields_for("#{name}[#{
106
- options[:child_index] || nested_child_index(name)
107
- }]", child, options, &block)
118
+ objects.inject(ActiveSupport::SafeBuffer.new) do |output, child|
119
+ output << @template.fields_for("#{name}[#{options[:child_index] ||
120
+ nested_child_index(name)}]", child, options, &block)
108
121
  end
109
- output
110
122
  end
111
123
 
112
124
  def predicate_select(options = {}, html_options = {})
113
125
  options[:compounds] = true if options[:compounds].nil?
114
- default = options.delete(:default) || 'cont'.freeze
126
+ default = options.delete(:default) || Constants::CONT
115
127
 
116
- keys = options[:compounds] ? Predicate.names :
128
+ keys =
129
+ if options[:compounds]
130
+ Predicate.names
131
+ else
117
132
  Predicate.names.reject { |k| k.match(/_(any|all)$/) }
133
+ end
118
134
  if only = options[:only]
119
135
  if only.respond_to? :call
120
136
  keys = keys.select { |k| only.call(k) }
121
137
  else
122
138
  only = Array.wrap(only).map(&:to_s)
123
139
  keys = keys.select {
124
- |k| only.include? k.sub(/_(any|all)$/, Ransack::Constants::EMPTY)
140
+ |k| only.include? k.sub(/_(any|all)$/, Constants::EMPTY)
125
141
  }
126
142
  end
127
143
  end
128
144
  collection = keys.map { |k| [k, Translate.predicate(k)] }
129
- object.predicate ||= Predicate.named(default) if can_use_default?(
130
- default, :predicate, keys
131
- )
145
+ object.predicate ||= Predicate.named(default) if
146
+ can_use_default?(default, :predicate, keys)
132
147
  template_collection_select(:p, collection, options, html_options)
133
148
  end
134
149
 
@@ -164,21 +179,21 @@ module Ransack
164
179
 
165
180
  def sort_array
166
181
  [
167
- [Ransack::Constants::ASC, object.translate(Ransack::Constants::ASC)],
168
- [Ransack::Constants::DESC, object.translate(Ransack::Constants::DESC)]
182
+ [Constants::ASC, object.translate(Constants::ASC)],
183
+ [Constants::DESC, object.translate(Constants::DESC)]
169
184
  ]
170
185
  end
171
186
 
172
187
  def combinator_choices
173
188
  if Nodes::Condition === object
174
189
  [
175
- [Ransack::Constants::OR, Translate.word(:any)],
176
- [Ransack::Constants::AND, Translate.word(:all)]
190
+ [Constants::OR, Translate.word(:any)],
191
+ [Constants::AND, Translate.word(:all)]
177
192
  ]
178
193
  else
179
194
  [
180
- [Ransack::Constants::AND, Translate.word(:all)],
181
- [Ransack::Constants::OR, Translate.word(:any)]
195
+ [Constants::AND, Translate.word(:all)],
196
+ [Constants::OR, Translate.word(:any)]
182
197
  ]
183
198
  end
184
199
  end
@@ -186,8 +201,7 @@ module Ransack
186
201
  def association_array(obj, prefix = nil)
187
202
  ([prefix] + association_object(obj))
188
203
  .compact
189
- .flatten
190
- .map { |v| [prefix, v].compact.join(Ransack::Constants::UNDERSCORE) }
204
+ .flat_map { |v| [prefix, v].compact.join(Constants::UNDERSCORE) }
191
205
  end
192
206
 
193
207
  def association_object(obj)
@@ -207,7 +221,7 @@ module Ransack
207
221
  when Array, Hash
208
222
  association_array(value, key.to_s)
209
223
  else
210
- [key.to_s, [key, value].join(Ransack::Constants::UNDERSCORE)]
224
+ [key.to_s, [key, value].join(Constants::UNDERSCORE)]
211
225
  end
212
226
  end
213
227
  end
@@ -218,8 +232,10 @@ module Ransack
218
232
 
219
233
  def get_attribute_element(action, base)
220
234
  begin
221
- [Translate.association(base, :context => object.context),
222
- collection_for_base(action, base)]
235
+ [
236
+ Translate.association(base, :context => object.context),
237
+ collection_for_base(action, base)
238
+ ]
223
239
  rescue UntraversableAssociationError => e
224
240
  nil
225
241
  end
@@ -227,10 +243,10 @@ module Ransack
227
243
 
228
244
  def attribute_collection_for_base(attributes, base = nil)
229
245
  attributes.map do |c|
230
- [attr_from_base_and_column(base, c),
246
+ [
247
+ attr_from_base_and_column(base, c),
231
248
  Translate.attribute(
232
- attr_from_base_and_column(base, c),
233
- :context => object.context
249
+ attr_from_base_and_column(base, c), :context => object.context
234
250
  )
235
251
  ]
236
252
  end
@@ -242,13 +258,11 @@ module Ransack
242
258
  end
243
259
 
244
260
  def attr_from_base_and_column(base, column)
245
- [base, column].reject { |v| v.blank? }
246
- .join(Ransack::Constants::UNDERSCORE)
261
+ [base, column].reject(&:blank?).join(Constants::UNDERSCORE)
247
262
  end
248
263
 
249
264
  def formbuilder_error_message(action)
250
- "#{
251
- action.sub(Ransack::Constants::SEARCH, Ransack::Constants::ATTRIBUTE)
265
+ "#{action.sub(Constants::SEARCH, Constants::ATTRIBUTE)
252
266
  } must be called inside a search FormBuilder!"
253
267
  end
254
268