ransack 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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