ransack 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +40 -22
  3. data/CHANGELOG.md +176 -27
  4. data/CONTRIBUTING.md +30 -19
  5. data/Gemfile +8 -3
  6. data/README.md +131 -58
  7. data/Rakefile +5 -2
  8. data/lib/ransack.rb +10 -5
  9. data/lib/ransack/adapters.rb +43 -23
  10. data/lib/ransack/adapters/active_record.rb +2 -2
  11. data/lib/ransack/adapters/active_record/3.0/compat.rb +5 -5
  12. data/lib/ransack/adapters/active_record/3.0/context.rb +5 -3
  13. data/lib/ransack/adapters/active_record/3.1/context.rb +1 -4
  14. data/lib/ransack/adapters/active_record/base.rb +12 -1
  15. data/lib/ransack/adapters/active_record/context.rb +148 -55
  16. data/lib/ransack/adapters/active_record/ransack/constants.rb +53 -53
  17. data/lib/ransack/adapters/active_record/ransack/context.rb +3 -1
  18. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +20 -28
  19. data/lib/ransack/adapters/mongoid/base.rb +21 -6
  20. data/lib/ransack/adapters/mongoid/context.rb +9 -5
  21. data/lib/ransack/configuration.rb +24 -3
  22. data/lib/ransack/constants.rb +11 -22
  23. data/lib/ransack/context.rb +20 -13
  24. data/lib/ransack/helpers/form_builder.rb +5 -6
  25. data/lib/ransack/helpers/form_helper.rb +50 -69
  26. data/lib/ransack/locale/da.yml +70 -0
  27. data/lib/ransack/locale/id.yml +70 -0
  28. data/lib/ransack/locale/ja.yml +70 -0
  29. data/lib/ransack/locale/pt-BR.yml +70 -0
  30. data/lib/ransack/locale/{zh.yml → zh-CN.yml} +1 -1
  31. data/lib/ransack/locale/zh-TW.yml +70 -0
  32. data/lib/ransack/nodes.rb +1 -1
  33. data/lib/ransack/nodes/attribute.rb +4 -1
  34. data/lib/ransack/nodes/bindable.rb +18 -6
  35. data/lib/ransack/nodes/condition.rb +58 -28
  36. data/lib/ransack/nodes/grouping.rb +15 -4
  37. data/lib/ransack/nodes/sort.rb +9 -5
  38. data/lib/ransack/predicate.rb +6 -2
  39. data/lib/ransack/search.rb +6 -5
  40. data/lib/ransack/translate.rb +2 -2
  41. data/lib/ransack/version.rb +1 -1
  42. data/ransack.gemspec +4 -4
  43. data/spec/mongoid/adapters/mongoid/base_spec.rb +20 -1
  44. data/spec/mongoid/nodes/condition_spec.rb +15 -0
  45. data/spec/mongoid/support/mongoid.yml +5 -0
  46. data/spec/mongoid/support/schema.rb +4 -0
  47. data/spec/mongoid_spec_helper.rb +13 -9
  48. data/spec/ransack/adapters/active_record/base_spec.rb +249 -71
  49. data/spec/ransack/adapters/active_record/context_spec.rb +16 -18
  50. data/spec/ransack/helpers/form_builder_spec.rb +5 -2
  51. data/spec/ransack/helpers/form_helper_spec.rb +84 -14
  52. data/spec/ransack/nodes/condition_spec.rb +24 -0
  53. data/spec/ransack/nodes/grouping_spec.rb +56 -0
  54. data/spec/ransack/predicate_spec.rb +5 -5
  55. data/spec/ransack/search_spec.rb +79 -70
  56. data/spec/support/schema.rb +43 -29
  57. metadata +17 -12
@@ -27,6 +27,8 @@ module Ransack
27
27
  @join_dependency = join_dependency(@object)
28
28
  @join_type = options[:join_type] || Polyamorous::OuterJoin
29
29
  @search_key = options[:search_key] || Ransack.options[:search_key]
30
+ @associations_pot = {}
31
+ @lock_associations = []
30
32
 
31
33
  if ::ActiveRecord::VERSION::STRING >= Constants::RAILS_4_1
32
34
  @base = @join_dependency.join_root
@@ -40,7 +42,7 @@ module Ransack
40
42
  @base.table_name, as: @base.aliased_table_name, type_caster: self
41
43
  )
42
44
  @bind_pairs = Hash.new do |hash, key|
43
- parent, attr_name = get_parent_and_attribute_name(key.to_s)
45
+ parent, attr_name = get_parent_and_attribute_name(key)
44
46
  if parent && attr_name
45
47
  hash[key] = [parent, attr_name]
46
48
  end
@@ -3,41 +3,33 @@ module Ransack
3
3
  class Condition
4
4
 
5
5
  def arel_predicate
6
- arel_predicate_for(attributes_array)
6
+ attributes.map { |attribute|
7
+ association = attribute.parent
8
+ if negative? && attribute.associated_collection?
9
+ query = context.build_correlated_subquery(association)
10
+ query.where(format_predicate(attribute).not)
11
+ context.remove_association(association)
12
+ Arel::Nodes::NotIn.new(context.primary_key, Arel.sql(query.to_sql))
13
+ else
14
+ format_predicate(attribute)
15
+ end
16
+ }.reduce(combinator_method)
7
17
  end
8
18
 
9
19
  private
10
20
 
11
- def attributes_array
12
- attributes.map do |a|
13
- a.attr.send(
14
- arel_predicate_for_attribute(a), formatted_values_for_attribute(a)
15
- )
16
- end
17
- end
18
-
19
- def arel_predicate_for(predicates)
20
- if predicates.size > 1
21
- combinator_for(predicates)
22
- else
23
- format_predicate(predicates.first)
24
- end
25
- end
26
-
27
- def combinator_for(predicates)
28
- if combinator === Constants::AND
29
- Arel::Nodes::Grouping.new(Arel::Nodes::And.new(predicates))
30
- elsif combinator === Constants::OR
31
- predicates.inject(&:or)
32
- end
21
+ def combinator_method
22
+ combinator === Constants::OR ? :or : :and
33
23
  end
34
24
 
35
- def format_predicate(predicate)
36
- predicate.tap do
37
- if casted_array_with_in_predicate?(predicate)
38
- predicate.right[0] = format_values_for(predicate.right[0])
39
- end
25
+ def format_predicate(attribute)
26
+ arel_pred = arel_predicate_for_attribute(attribute)
27
+ arel_values = formatted_values_for_attribute(attribute)
28
+ predicate = attribute.attr.public_send(arel_pred, arel_values)
29
+ if casted_array_with_in_predicate?(predicate)
30
+ predicate.right[0] = format_values_for(predicate.right[0])
40
31
  end
32
+ predicate
41
33
  end
42
34
 
43
35
  def casted_array_with_in_predicate?(predicate)
@@ -33,6 +33,14 @@ module Ransack
33
33
  end
34
34
 
35
35
  module ClassMethods
36
+ def _ransack_aliases
37
+ @_ransack_aliases ||= {}
38
+ end
39
+
40
+ def _ransack_aliases=(value)
41
+ @_ransack_aliases = value
42
+ end
43
+
36
44
  def _ransackers
37
45
  @_ransackers ||= {}
38
46
  end
@@ -49,13 +57,18 @@ module Ransack
49
57
 
50
58
  alias_method :search, :ransack
51
59
 
60
+ def ransack_alias(new_name, old_name)
61
+ self._ransack_aliases.store(new_name.to_s, old_name.to_s)
62
+ end
63
+
52
64
  def ransacker(name, opts = {}, &block)
53
65
  self._ransackers = _ransackers.merge name.to_s => Ransacker
54
66
  .new(self, name, opts, &block)
55
67
  end
56
68
 
57
69
  def all_ransackable_attributes
58
- ['id'] + column_names.select { |c| c != '_id' } + _ransackers.keys
70
+ ['id'] + column_names.select { |c| c != '_id' } + _ransackers.keys +
71
+ _ransack_aliases.keys
59
72
  end
60
73
 
61
74
  def ransackable_attributes(auth_object = nil)
@@ -73,7 +86,9 @@ module Ransack
73
86
  end
74
87
 
75
88
  def reflect_on_all_associations_all
76
- reflect_on_all_associations(:belongs_to, :has_one, :has_many, :embeds_many, :embedded_in)
89
+ reflect_on_all_associations(
90
+ :belongs_to, :has_one, :has_many, :embeds_many, :embedded_in
91
+ )
77
92
  end
78
93
 
79
94
  # For overriding with a whitelist of symbols
@@ -116,10 +131,10 @@ module Ransack
116
131
  end
117
132
 
118
133
  def table
119
- name = ::Ransack::Adapters::Mongoid::Attributes::Attribute.new(self.criteria, :name)
120
- {
121
- :name => name
122
- }
134
+ name = ::Ransack::Adapters::Mongoid::Attributes::Attribute.new(
135
+ self.criteria, :name
136
+ )
137
+ { :name => name }
123
138
  end
124
139
 
125
140
  end
@@ -6,10 +6,6 @@ module Ransack
6
6
  module Mongoid
7
7
  class Context < ::Ransack::Context
8
8
 
9
- # Because the AR::Associations namespace is insane
10
- # JoinDependency = ::Mongoid::Associations::JoinDependency
11
- # JoinPart = JoinDependency::JoinPart
12
-
13
9
  def initialize(object, options = {})
14
10
  super
15
11
  # @arel_visitor = @engine.connection.visitor
@@ -100,6 +96,14 @@ module Ransack
100
96
  end
101
97
  end
102
98
 
99
+ def lock_association(association)
100
+ warn "lock_association is not implemented for Ransack mongoid adapter" if $DEBUG
101
+ end
102
+
103
+ def remove_association(association)
104
+ warn "remove_association is not implemented for Ransack mongoid adapter" if $DEBUG
105
+ end
106
+
103
107
  private
104
108
 
105
109
  def get_parent_and_attribute_name(str, parent = @base)
@@ -132,7 +136,7 @@ module Ransack
132
136
  end
133
137
 
134
138
  def join_dependency(relation)
135
- if relation.respond_to?(:join_dependency) # Squeel will enable this
139
+ if relation.respond_to?(:join_dependency) # Polyamorous enables this
136
140
  relation.join_dependency
137
141
  else
138
142
  build_join_dependency(relation)
@@ -8,7 +8,8 @@ module Ransack
8
8
  self.predicates = {}
9
9
  self.options = {
10
10
  :search_key => :q,
11
- :ignore_unknown_conditions => true
11
+ :ignore_unknown_conditions => true,
12
+ :hide_sort_order_indicators => false
12
13
  }
13
14
 
14
15
  def configure
@@ -61,12 +62,32 @@ module Ransack
61
62
  self.options[:search_key] = name
62
63
  end
63
64
 
64
- # Raise an error if an unknown predicate, condition or attribute is passed
65
- # into a search.
65
+ # By default Ransack ignores errors if an unknown predicate, condition or
66
+ # attribute is passed into a search. The default may be overridden in an
67
+ # initializer file like `config/initializers/ransack.rb` as follows:
68
+ #
69
+ # Ransack.configure do |config|
70
+ # # Raise if an unknown predicate, condition or attribute is passed
71
+ # config.ignore_unknown_conditions = false
72
+ # end
73
+ #
66
74
  def ignore_unknown_conditions=(boolean)
67
75
  self.options[:ignore_unknown_conditions] = boolean
68
76
  end
69
77
 
78
+ # By default, Ransack displays sort order indicator arrows in sort links.
79
+ # The default may be globally overridden in an initializer file like
80
+ # `config/initializers/ransack.rb` as follows:
81
+ #
82
+ # Ransack.configure do |config|
83
+ # # Hide sort link order indicators globally across the application
84
+ # config.hide_sort_order_indicators = true
85
+ # end
86
+ #
87
+ def hide_sort_order_indicators=(boolean)
88
+ self.options[:hide_sort_order_indicators] = boolean
89
+ end
90
+
70
91
  def arel_predicate_with_suffix(arel_predicate, suffix)
71
92
  if arel_predicate === Proc
72
93
  proc { |v| "#{arel_predicate.call(v)}#{suffix}" }
@@ -1,19 +1,10 @@
1
1
  module Ransack
2
2
  module Constants
3
- ASC = 'asc'.freeze
4
- DESC = 'desc'.freeze
5
- ASC_DESC = [ASC, DESC].freeze
6
-
7
3
  ASC_ARROW = '&#9650;'.freeze
8
4
  DESC_ARROW = '&#9660;'.freeze
9
5
 
10
6
  OR = 'or'.freeze
11
7
  AND = 'and'.freeze
12
- SPACED_AND = ' AND '.freeze
13
-
14
- SORT = 'sort'.freeze
15
- SORT_LINK = 'sort_link'.freeze
16
- SORT_DIRECTION = 'sort_direction'.freeze
17
8
 
18
9
  CAP_SEARCH = 'Search'.freeze
19
10
  SEARCH = 'search'.freeze
@@ -23,17 +14,12 @@ module Ransack
23
14
  ATTRIBUTES = 'attributes'.freeze
24
15
  COMBINATOR = 'combinator'.freeze
25
16
 
26
- SPACE = ' '.freeze
27
- COMMA_SPACE = ', '.freeze
28
- COLON_SPACE = ': '.freeze
29
17
  TWO_COLONS = '::'.freeze
30
18
  UNDERSCORE = '_'.freeze
31
19
  LEFT_PARENTHESIS = '('.freeze
32
20
  Q = 'q'.freeze
33
21
  I = 'i'.freeze
34
- NON_BREAKING_SPACE = '&nbsp;'.freeze
35
22
  DOT_ASTERIX = '.*'.freeze
36
- EMPTY = ''.freeze
37
23
 
38
24
  STRING_JOIN = 'string_join'.freeze
39
25
  ASSOCIATION_JOIN = 'association_join'.freeze
@@ -44,14 +30,17 @@ module Ransack
44
30
  FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
45
31
  BOOLEAN_VALUES = (TRUE_VALUES + FALSE_VALUES).freeze
46
32
 
47
- S_SORTS = %w(s sorts).freeze
48
- AND_OR = %w(and or).freeze
49
- IN_NOT_IN = %w(in not_in).freeze
50
- SUFFIXES = %w(_any _all).freeze
51
- AREL_PREDICATES = %w(
52
- eq not_eq matches does_not_match lt lteq gt gteq in not_in
53
- ).freeze
54
- A_S_I = %w(a s i).freeze
33
+ AND_OR = ['and'.freeze, 'or'.freeze].freeze
34
+ IN_NOT_IN = ['in'.freeze, 'not_in'.freeze].freeze
35
+ SUFFIXES = ['_any'.freeze, '_all'.freeze].freeze
36
+ AREL_PREDICATES = [
37
+ 'eq'.freeze, 'not_eq'.freeze,
38
+ 'matches'.freeze, 'does_not_match'.freeze,
39
+ 'lt'.freeze, 'lteq'.freeze,
40
+ 'gt'.freeze, 'gteq'.freeze,
41
+ 'in'.freeze, 'not_in'.freeze
42
+ ].freeze
43
+ A_S_I = ['a'.freeze, 's'.freeze, 'i'.freeze].freeze
55
44
 
56
45
  EQ = 'eq'.freeze
57
46
  NOT_EQ = 'not_eq'.freeze
@@ -1,5 +1,5 @@
1
1
  require 'ransack/visitor'
2
- Ransack::Adapters.require_context
2
+ Ransack::Adapters.object_mapper.require_context
3
3
 
4
4
  module Ransack
5
5
  class Context
@@ -17,9 +17,12 @@ module Ransack
17
17
  end
18
18
 
19
19
  def for(object, options = {})
20
- context = Class === object ?
21
- for_class(object, options) :
22
- for_object(object, options)
20
+ context =
21
+ if Class === object
22
+ for_class(object, options)
23
+ else
24
+ for_object(object, options)
25
+ end
23
26
  context or raise ArgumentError,
24
27
  "Don't know what context to use for #{object}"
25
28
  end
@@ -55,11 +58,12 @@ module Ransack
55
58
  end
56
59
 
57
60
  def bind(object, str)
61
+ return nil unless str
58
62
  object.parent, object.attr_name = @bind_pairs[str]
59
63
  end
60
64
 
61
65
  def traverse(str, base = @base)
62
- str ||= Constants::EMPTY
66
+ str ||= ''.freeze
63
67
 
64
68
  if (segments = str.split(/_/)).size > 0
65
69
  remainder = []
@@ -68,13 +72,12 @@ module Ransack
68
72
  # Strip the _of_Model_type text from the association name, but hold
69
73
  # onto it in klass, for use as the next base
70
74
  assoc, klass = unpolymorphize_association(
71
- segments.join(Constants::UNDERSCORE)
75
+ segments.join('_'.freeze)
72
76
  )
73
77
  if found_assoc = get_association(assoc, base)
74
78
  base = traverse(
75
- remainder.join(
76
- Constants::UNDERSCORE), klass || found_assoc.klass
77
- )
79
+ remainder.join('_'.freeze), klass || found_assoc.klass
80
+ )
78
81
  end
79
82
 
80
83
  remainder.unshift segments.pop
@@ -88,7 +91,7 @@ module Ransack
88
91
 
89
92
  def association_path(str, base = @base)
90
93
  base = klassify(base)
91
- str ||= Constants::EMPTY
94
+ str ||= ''.freeze
92
95
  path = []
93
96
  segments = str.split(/_/)
94
97
  association_parts = []
@@ -118,6 +121,10 @@ module Ransack
118
121
  end
119
122
  end
120
123
 
124
+ def ransackable_alias(str)
125
+ klass._ransack_aliases.fetch(str, str)
126
+ end
127
+
121
128
  def ransackable_attribute?(str, klass)
122
129
  klass.ransackable_attributes(auth_object).include?(str) ||
123
130
  klass.ransortable_attributes(auth_object).include?(str)
@@ -131,15 +138,15 @@ module Ransack
131
138
  klass.ransackable_scopes(auth_object).any? { |s| s.to_s == str }
132
139
  end
133
140
 
134
- def searchable_attributes(str = Constants::EMPTY)
141
+ def searchable_attributes(str = ''.freeze)
135
142
  traverse(str).ransackable_attributes(auth_object)
136
143
  end
137
144
 
138
- def sortable_attributes(str = Constants::EMPTY)
145
+ def sortable_attributes(str = ''.freeze)
139
146
  traverse(str).ransortable_attributes(auth_object)
140
147
  end
141
148
 
142
- def searchable_associations(str = Constants::EMPTY)
149
+ def searchable_associations(str = ''.freeze)
143
150
  traverse(str).ransackable_associations(auth_object)
144
151
  end
145
152
  end
@@ -15,8 +15,7 @@ end
15
15
  RANSACK_FORM_BUILDER = 'RANSACK_FORM_BUILDER'.freeze
16
16
 
17
17
  require 'simple_form' if
18
- (ENV[RANSACK_FORM_BUILDER] || Ransack::Constants::EMPTY)
19
- .match('SimpleForm'.freeze)
18
+ (ENV[RANSACK_FORM_BUILDER] || ''.freeze).match('SimpleForm'.freeze)
20
19
 
21
20
  module Ransack
22
21
  module Helpers
@@ -47,7 +46,7 @@ module Ransack
47
46
  raise ArgumentError, formbuilder_error_message(
48
47
  "#{action}_select") unless object.respond_to?(:context)
49
48
  options[:include_blank] = true unless options.has_key?(:include_blank)
50
- bases = [Constants::EMPTY] + association_array(options[:associations])
49
+ bases = [''.freeze].freeze + association_array(options[:associations])
51
50
  if bases.size > 1
52
51
  collection = attribute_collection_for_bases(action, bases)
53
52
  object.name ||= default if can_use_default?(
@@ -66,13 +65,13 @@ module Ransack
66
65
  def sort_direction_select(options = {}, html_options = {})
67
66
  unless object.respond_to?(:context)
68
67
  raise ArgumentError,
69
- formbuilder_error_message(Constants::SORT_DIRECTION)
68
+ formbuilder_error_message('sort_direction'.freeze)
70
69
  end
71
70
  template_collection_select(:dir, sort_array, options, html_options)
72
71
  end
73
72
 
74
73
  def sort_select(options = {}, html_options = {})
75
- attribute_select(options, html_options, Constants::SORT) +
74
+ attribute_select(options, html_options, 'sort'.freeze) +
76
75
  sort_direction_select(options, html_options)
77
76
  end
78
77
 
@@ -135,7 +134,7 @@ module Ransack
135
134
  else
136
135
  only = Array.wrap(only).map(&:to_s)
137
136
  keys = keys.select {
138
- |k| only.include? k.sub(/_(any|all)$/, Constants::EMPTY)
137
+ |k| only.include? k.sub(/_(any|all)$/, ''.freeze)
139
138
  }
140
139
  end
141
140
  end
@@ -38,43 +38,41 @@ module Ransack
38
38
  #
39
39
  # <%= sort_link(@q, :name, [:name, 'kind ASC'], 'Player Name') %>
40
40
  #
41
- def sort_link(search_object, attribute, *args)
41
+ # You can also use a block:
42
+ #
43
+ # <%= sort_link(@q, :name, [:name, 'kind ASC']) do %>
44
+ # <strong>Player Name</strong>
45
+ # <% end %>
46
+ #
47
+ def sort_link(search_object, attribute, *args, &block)
42
48
  search, routing_proxy = extract_search_and_routing_proxy(search_object)
43
49
  unless Search === search
44
50
  raise TypeError, 'First argument must be a Ransack::Search!'
45
51
  end
46
- s = SortLink.new(search, attribute, args, params)
52
+ args.unshift(capture(&block)) if block_given?
53
+ s = SortLink.new(search, attribute, args, params, &block)
47
54
  link_to(s.name, url(routing_proxy, s.url_options), s.html_options(args))
48
55
  end
49
56
 
50
57
  private
51
58
 
52
59
  def options_for(record)
53
- record.map &method(:parse_record)
60
+ record.map { |r| parse_record(r) }
54
61
  end
55
62
 
56
63
  def parse_record(object)
57
- if object.is_a?(Ransack::Search)
58
- object.klass
59
- else
60
- object
61
- end
64
+ return object.klass if object.is_a?(Ransack::Search)
65
+ object
62
66
  end
63
67
 
64
68
  def html_option_for(option, search)
65
- if option.present?
66
- option.to_s
67
- else
68
- "#{search.klass.to_s.underscore}_search"
69
- end
69
+ return option.to_s if option.present?
70
+ "#{search.klass.to_s.underscore}_search"
70
71
  end
71
72
 
72
73
  def extract_search_and_routing_proxy(search)
73
- if search.is_a? Array
74
- [search.second, search.first]
75
- else
76
- [search, nil]
77
- end
74
+ return [search[1], search[0]] if search.is_a?(Array)
75
+ [search, nil]
78
76
  end
79
77
 
80
78
  def url(routing_proxy, options_for_url)
@@ -88,20 +86,21 @@ module Ransack
88
86
  class SortLink
89
87
  def initialize(search, attribute, args, params)
90
88
  @search = search
91
- @params = params
89
+ @params = parameters_hash(params)
92
90
  @field = attribute.to_s
93
91
  @sort_fields = extract_sort_fields_and_mutate_args!(args).compact
94
92
  @current_dir = existing_sort_direction
95
93
  @label_text = extract_label_and_mutate_args!(args)
96
94
  @options = extract_options_and_mutate_args!(args)
97
- @hide_indicator = @options.delete :hide_indicator
95
+ @hide_indicator = @options.delete(:hide_indicator) ||
96
+ Ransack.options[:hide_sort_order_indicators]
98
97
  @default_order = @options.delete :default_order
99
98
  end
100
99
 
101
100
  def name
102
101
  [ERB::Util.h(@label_text), order_indicator]
103
102
  .compact
104
- .join(Constants::NON_BREAKING_SPACE)
103
+ .join('&nbsp;'.freeze)
105
104
  .html_safe
106
105
  end
107
106
 
@@ -114,35 +113,34 @@ module Ransack
114
113
  def html_options(args)
115
114
  html_options = extract_options_and_mutate_args!(args)
116
115
  html_options.merge(
117
- class: [[Constants::SORT_LINK, @current_dir], html_options[:class]]
118
- .compact.join(Constants::SPACE)
116
+ class: [['sort_link'.freeze, @current_dir], html_options[:class]]
117
+ .compact.join(' '.freeze)
119
118
  )
120
119
  end
121
120
 
122
121
  private
123
122
 
124
- def extract_sort_fields_and_mutate_args!(args)
125
- if args.first.is_a? Array
126
- args.shift
123
+ def parameters_hash(params)
124
+ if ::ActiveRecord::VERSION::MAJOR == 5 && params.respond_to?(:to_unsafe_h)
125
+ params.to_unsafe_h
127
126
  else
128
- [@field]
127
+ params
129
128
  end
130
129
  end
131
130
 
131
+ def extract_sort_fields_and_mutate_args!(args)
132
+ return args.shift if args[0].is_a?(Array)
133
+ [@field]
134
+ end
135
+
132
136
  def extract_label_and_mutate_args!(args)
133
- if args.first.is_a? String
134
- args.shift
135
- else
136
- Translate.attribute(@field, context: @search.context)
137
- end
137
+ return args.shift if args[0].is_a?(String)
138
+ Translate.attribute(@field, context: @search.context)
138
139
  end
139
140
 
140
141
  def extract_options_and_mutate_args!(args)
141
- if args.first.is_a? Hash
142
- args.shift.with_indifferent_access
143
- else
144
- {}
145
- end
142
+ return args.shift.with_indifferent_access if args[0].is_a?(Hash)
143
+ {}
146
144
  end
147
145
 
148
146
  def search_and_sort_params
@@ -155,11 +153,8 @@ module Ransack
155
153
 
156
154
  def sort_params
157
155
  sort_array = recursive_sort_params_build(@sort_fields)
158
- if sort_array.size == 1
159
- sort_array.first
160
- else
161
- sort_array
162
- end
156
+ return sort_array[0] if sort_array.length == 1
157
+ sort_array
163
158
  end
164
159
 
165
160
  def recursive_sort_params_build(fields)
@@ -179,52 +174,38 @@ module Ransack
179
174
  if sort_dir = existing_sort_direction(attr_name)
180
175
  direction_text(sort_dir)
181
176
  else
182
- default_sort_order(attr_name) || Constants::ASC
177
+ default_sort_order(attr_name) || 'asc'.freeze
183
178
  end
184
179
  end
185
180
 
186
- def existing_sort_direction(attr_name = @field)
187
- if sort = @search.sorts.detect { |s| s && s.name == attr_name }
188
- sort.dir
189
- end
181
+ def existing_sort_direction(f = @field)
182
+ return unless sort = @search.sorts.detect { |s| s && s.name == f }
183
+ sort.dir
190
184
  end
191
185
 
192
186
  def default_sort_order(attr_name)
193
- if Hash === @default_order
194
- @default_order[attr_name]
195
- else
196
- @default_order
197
- end
187
+ return @default_order[attr_name] if Hash === @default_order
188
+ @default_order
198
189
  end
199
190
 
200
191
  def order_indicator
201
- if @hide_indicator || no_sort_direction_specified?
202
- nil
203
- else
204
- direction_arrow
205
- end
192
+ return if @hide_indicator || no_sort_direction_specified?
193
+ direction_arrow
206
194
  end
207
195
 
208
196
  def no_sort_direction_specified?(dir = @current_dir)
209
- !Constants::ASC_DESC.include?(dir)
197
+ !['asc'.freeze, 'desc'.freeze].freeze.include?(dir)
210
198
  end
211
199
 
212
200
  def direction_arrow
213
- if @current_dir == Constants::DESC
214
- Constants::DESC_ARROW
215
- else
216
- Constants::ASC_ARROW
217
- end
201
+ return Constants::DESC_ARROW if @current_dir == 'desc'.freeze
202
+ Constants::ASC_ARROW
218
203
  end
219
204
 
220
205
  def direction_text(dir)
221
- if dir == Constants::DESC
222
- Constants::ASC
223
- else
224
- Constants::DESC
225
- end
206
+ return 'asc'.freeze if dir == 'desc'.freeze
207
+ 'desc'.freeze
226
208
  end
227
-
228
209
  end
229
210
  end
230
211
  end