datagrid 1.8.2 → 2.0.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -1
  3. data/{Readme.markdown → README.md} +44 -27
  4. data/app/assets/stylesheets/datagrid.css +145 -0
  5. data/app/views/datagrid/_enum_checkboxes.html.erb +5 -3
  6. data/app/views/datagrid/_form.html.erb +4 -4
  7. data/app/views/datagrid/_head.html.erb +26 -3
  8. data/app/views/datagrid/_range_filter.html.erb +5 -3
  9. data/app/views/datagrid/_row.html.erb +12 -1
  10. data/app/views/datagrid/_table.html.erb +4 -4
  11. data/datagrid.gemspec +6 -6
  12. data/lib/datagrid/active_model.rb +9 -17
  13. data/lib/datagrid/base.rb +39 -0
  14. data/lib/datagrid/column_names_attribute.rb +9 -11
  15. data/lib/datagrid/columns/column.rb +155 -133
  16. data/lib/datagrid/columns.rb +254 -45
  17. data/lib/datagrid/configuration.rb +23 -10
  18. data/lib/datagrid/core.rb +89 -54
  19. data/lib/datagrid/deprecated_object.rb +20 -0
  20. data/lib/datagrid/drivers/abstract_driver.rb +12 -23
  21. data/lib/datagrid/drivers/active_record.rb +24 -26
  22. data/lib/datagrid/drivers/array.rb +22 -14
  23. data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
  24. data/lib/datagrid/drivers/mongoid.rb +15 -17
  25. data/lib/datagrid/drivers/sequel.rb +14 -19
  26. data/lib/datagrid/drivers.rb +2 -1
  27. data/lib/datagrid/engine.rb +11 -3
  28. data/lib/datagrid/filters/base_filter.rb +166 -142
  29. data/lib/datagrid/filters/boolean_filter.rb +19 -5
  30. data/lib/datagrid/filters/date_filter.rb +33 -35
  31. data/lib/datagrid/filters/date_time_filter.rb +24 -16
  32. data/lib/datagrid/filters/default_filter.rb +9 -3
  33. data/lib/datagrid/filters/dynamic_filter.rb +151 -105
  34. data/lib/datagrid/filters/enum_filter.rb +43 -19
  35. data/lib/datagrid/filters/extended_boolean_filter.rb +39 -30
  36. data/lib/datagrid/filters/float_filter.rb +16 -5
  37. data/lib/datagrid/filters/integer_filter.rb +21 -10
  38. data/lib/datagrid/filters/ranged_filter.rb +66 -45
  39. data/lib/datagrid/filters/select_options.rb +58 -49
  40. data/lib/datagrid/filters/string_filter.rb +9 -4
  41. data/lib/datagrid/filters.rb +190 -57
  42. data/lib/datagrid/form_builder.rb +116 -128
  43. data/lib/datagrid/generators/scaffold.rb +185 -0
  44. data/lib/datagrid/generators/views.rb +20 -0
  45. data/lib/datagrid/helper.rb +397 -22
  46. data/lib/datagrid/ordering.rb +26 -29
  47. data/lib/datagrid/rspec.rb +6 -10
  48. data/lib/datagrid/utils.rb +37 -30
  49. data/lib/datagrid/version.rb +3 -1
  50. data/lib/datagrid.rb +18 -28
  51. data/templates/base.rb.erb +6 -4
  52. data/templates/grid.rb.erb +1 -1
  53. metadata +15 -16
  54. data/app/assets/stylesheets/datagrid.sass +0 -134
  55. data/lib/datagrid/filters/composite_filters.rb +0 -49
  56. data/lib/datagrid/renderer.rb +0 -157
  57. data/lib/datagrid/scaffold.rb +0 -129
  58. data/lib/tasks/datagrid_tasks.rake +0 -15
  59. data/templates/controller.rb.erb +0 -6
  60. data/templates/index.html.erb +0 -5
@@ -1,57 +1,66 @@
1
- module Datagrid::Filters::SelectOptions
2
- def select(object)
3
- select = self.options[:select]
4
- if select.is_a?(Symbol)
5
- object.send(select)
6
- elsif select.respond_to?(:call)
7
- Datagrid::Utils.apply_args(object, &select)
8
- else
9
- select
10
- end
11
- end
1
+ # frozen_string_literal: true
12
2
 
13
- def select_values(object)
14
- options = select(object)
15
- groups_used = grouped_choices?(options)
16
- options.map do |option|
17
- if groups_used
18
- option[1].map {|o| option_text_and_value(o)}
19
- else
20
- option_text_and_value(option)
3
+ module Datagrid
4
+ module Filters
5
+ module SelectOptions
6
+ def select(object)
7
+ select = options[:select]
8
+ if select.is_a?(Symbol)
9
+ object.send(select)
10
+ elsif select.respond_to?(:call)
11
+ Datagrid::Utils.apply_args(object, &select)
12
+ else
13
+ select
14
+ end
21
15
  end
22
- end.map(&:last)
23
- end
24
16
 
25
- def include_blank
26
- unless prompt
27
- options.has_key?(:include_blank) ?
28
- Datagrid::Utils.callable(options[:include_blank]) : !multiple?
29
- end
30
- end
17
+ def select_values(object)
18
+ options = select(object)
19
+ groups_used = grouped_choices?(options)
20
+ options.map do |option|
21
+ if groups_used
22
+ option[1].map { |o| option_text_and_value(o) }
23
+ else
24
+ option_text_and_value(option)
25
+ end
26
+ end.map(&:last)
27
+ end
31
28
 
32
- def prompt
33
- options.has_key?(:prompt) ? Datagrid::Utils.callable(options[:prompt]) : false
34
- end
29
+ def include_blank
30
+ return if prompt
35
31
 
36
- protected
37
-
38
- # Rails built-in method:
39
- # https://github.com/rails/rails/blob/94e80269e36caf7b2d22a7ab68e6898d3a824122/actionview/lib/action_view/helpers/form_options_helper.rb#L789
40
- # Code reuse is difficult, so it is easier to duplicate it
41
- def option_text_and_value(option)
42
- # Options are [text, value] pairs or strings used for both.
43
- if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
44
- option = option.reject { |e| Hash === e } if Array === option
45
- [option.first, option.last]
46
- else
47
- [option, option]
48
- end
49
- end
32
+ if options.key?(:include_blank)
33
+ Datagrid::Utils.callable(options[:include_blank])
34
+ else
35
+ !multiple?
36
+ end
37
+ end
38
+
39
+ def prompt
40
+ options.key?(:prompt) ? Datagrid::Utils.callable(options[:prompt]) : false
41
+ end
42
+
43
+ protected
50
44
 
51
- # Rails built-in method:
52
- # https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/actionview/lib/action_view/helpers/tags/select.rb#L36
53
- # Code reuse is difficult, so it is easier to duplicate it
54
- def grouped_choices?(choices)
55
- !choices.blank? && choices.first.respond_to?(:last) && Array === choices.first.last
45
+ # Rails built-in method:
46
+ # https://github.com/rails/rails/blob/94e80269e36caf7b2d22a7ab68e6898d3a824122/actionview/lib/action_view/helpers/form_options_helper.rb#L789
47
+ # Code reuse is difficult, so it is easier to duplicate it
48
+ def option_text_and_value(option)
49
+ # Options are [text, value] pairs or strings used for both.
50
+ if !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
51
+ option = option.reject { |e| e.is_a?(Hash) } if option.is_a?(Array)
52
+ [option.first, option.last]
53
+ else
54
+ [option, option]
55
+ end
56
+ end
57
+
58
+ # Rails built-in method:
59
+ # https://github.com/rails/rails/blob/f95c0b7e96eb36bc3efc0c5beffbb9e84ea664e4/actionview/lib/action_view/helpers/tags/select.rb#L36
60
+ # Code reuse is difficult, so it is easier to duplicate it
61
+ def grouped_choices?(choices)
62
+ !choices.blank? && choices.first.respond_to?(:last) && choices.first.last.is_a?(Array)
63
+ end
64
+ end
56
65
  end
57
66
  end
@@ -1,8 +1,13 @@
1
- class Datagrid::Filters::StringFilter < Datagrid::Filters::BaseFilter
1
+ # frozen_string_literal: true
2
2
 
3
- include Datagrid::Filters::RangedFilter
3
+ module Datagrid
4
+ module Filters
5
+ class StringFilter < Datagrid::Filters::BaseFilter
6
+ include Datagrid::Filters::RangedFilter
4
7
 
5
- def parse(value)
6
- value.nil? ? nil : value.to_s
8
+ def parse(value)
9
+ value&.to_s
10
+ end
11
+ end
7
12
  end
8
13
  end
@@ -1,8 +1,135 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/class/attribute"
2
4
 
3
5
  module Datagrid
6
+ # Defines the accessible attribute that is used to filter
7
+ # the scope by the specified value with specified code.
8
+ #
9
+ # class UserGrid < ApplicationGrid
10
+ # scope do
11
+ # User
12
+ # end
13
+ #
14
+ # filter(:name)
15
+ # filter(:posts_count, :integer) do |value|
16
+ # self.where(["posts_count >= ?", value])
17
+ # end
18
+ # end
19
+ #
20
+ # Each filter becomes a grid attribute.
21
+ #
22
+ # To create a grid displaying all users with the name 'John' who have more than zero posts:
23
+ #
24
+ # grid = UserGrid.new(posts_count: 1, name: "John")
25
+ # grid.assets # SELECT * FROM users WHERE users.posts_count > 1 AND name = 'John'
26
+ #
27
+ # # Filter Block
28
+ #
29
+ # Filter blocks should always return a chainable ORM object (e.g., `ActiveRecord::Relation`) rather than an `Array`.
30
+ #
31
+ # Filter blocks should have at least one argument representing the value assigned to the grid object attribute:
32
+ #
33
+ # filter(:name, :string) # { |value| where(name: value) }
34
+ #
35
+ # You can pass additional arguments:
36
+ #
37
+ # filter(:name, :string) { |value, scope| scope.where("name ilike ?", "%#{value}%") }
38
+ # filter(:name, :string) do |value, scope, grid|
39
+ # scope.where("name #{grid.predicate} ?", "%#{value}%")
40
+ # end
41
+ #
42
+ # # Filter Types
43
+ #
44
+ # Filters perform automatic type conversion. Supported filter types include:
45
+ #
46
+ # - `default`
47
+ # - `date`
48
+ # - `datetime`
49
+ # - `enum`
50
+ # - `boolean`
51
+ # - `xboolean`
52
+ # - `integer`
53
+ # - `float`
54
+ # - `string`
55
+ # - `dynamic`
56
+ #
57
+ # ## Default
58
+ #
59
+ # `:default` - Leaves the value as is.
60
+ #
61
+ # ## Date
62
+ #
63
+ # `:date` - Converts value to a date. Supports the `:range` option to accept date ranges.
64
+ #
65
+ # filter(:created_at, :date, range: true, default: proc { 1.month.ago.to_date..Date.today })
66
+ #
67
+ # ## Datetime
68
+ #
69
+ # `:datetime` - Converts value to a timestamp. Supports the `:range` option to accept time ranges.
70
+ #
71
+ # filter(:created_at, :datetime, range: true, default: proc { 1.hour.ago..Time.now })
72
+ #
73
+ # ## Enum
74
+ #
75
+ # `:enum` - For collection selection with options like `:select` and `:multiple`.
76
+ #
77
+ # filter(:user_type, :enum, select: ['Admin', 'Customer', 'Manager'])
78
+ # filter(:category_id, :enum, select: proc { Category.all.map { |c| [c.name, c.id] } }, multiple: true)
79
+ #
80
+ # ## Boolean
81
+ #
82
+ # `:boolean` - Converts value to `true` or `false`.
83
+ #
84
+ # ## Xboolean
85
+ #
86
+ # `:xboolean` - Subtype of `enum` filter that provides "Yes", "No", and "Any" options.
87
+ #
88
+ # filter(:active, :xboolean)
89
+ #
90
+ # ## Integer
91
+ #
92
+ # `:integer` - Converts value to an integer. Supports the `:range` option.
93
+ #
94
+ # filter(:posts_count, :integer, range: true, default: (1..nil))
95
+ #
96
+ # ## String
97
+ #
98
+ # `:string` - Converts value to a string.
99
+ #
100
+ # filter(:email, :string)
101
+ #
102
+ # ## Dynamic
103
+ #
104
+ # Provides a builder for dynamic SQL conditions.
105
+ #
106
+ # filter(:condition1, :dynamic)
107
+ # filter(:condition2, :dynamic)
108
+ # UsersGrid.new(condition1: [:name, "=~", "John"], condition2: [:posts_count, ">=", 1])
109
+ # UsersGrid.assets # SELECT * FROM users WHERE name like '%John%' and posts_count >= 1
110
+ #
111
+ # # Filter Options
112
+ #
113
+ # Options that can be passed to any filter:
114
+ #
115
+ # - `:header` - Human-readable filter name (default: generated from the filter name).
116
+ # - `:default` - Default filter value (default: `nil`).
117
+ # - `:multiple` - Allows multiple values (default: `false`).
118
+ # - `:allow_nil` - Whether to apply the filter when the value is `nil` (default: `false`).
119
+ # - `:allow_blank` - Whether to apply the filter when the value is blank (default: `false`).
120
+ #
121
+ # Example:
122
+ #
123
+ # filter(:id, :integer, header: "Identifier")
124
+ # filter(:created_at, :date, range: true, default: proc { 1.month.ago.to_date..Date.today })
125
+ #
126
+ # # Localization
127
+ #
128
+ # Filter labels can be localized or specified via the `:header` option:
129
+ #
130
+ # filter(:created_at, :date, header: "Creation date")
131
+ # filter(:created_at, :date, header: proc { I18n.t("creation_date") })
4
132
  module Filters
5
-
6
133
  require "datagrid/filters/base_filter"
7
134
  require "datagrid/filters/enum_filter"
8
135
  require "datagrid/filters/extended_boolean_filter"
@@ -11,49 +138,47 @@ module Datagrid
11
138
  require "datagrid/filters/date_time_filter"
12
139
  require "datagrid/filters/default_filter"
13
140
  require "datagrid/filters/integer_filter"
14
- require "datagrid/filters/composite_filters"
15
141
  require "datagrid/filters/string_filter"
16
142
  require "datagrid/filters/float_filter"
17
143
  require "datagrid/filters/dynamic_filter"
18
144
 
145
+ # @!visibility private
19
146
  FILTER_TYPES = {
20
147
  date: Filters::DateFilter,
21
148
  datetime: Filters::DateTimeFilter,
22
149
  string: Filters::StringFilter,
23
150
  default: Filters::DefaultFilter,
24
- xboolean: Filters::ExtendedBooleanFilter ,
25
- boolean: Filters::BooleanFilter ,
151
+ xboolean: Filters::ExtendedBooleanFilter,
152
+ boolean: Filters::BooleanFilter,
26
153
  integer: Filters::IntegerFilter,
27
154
  enum: Filters::EnumFilter,
28
155
  float: Filters::FloatFilter,
29
- dynamic: Filters::DynamicFilter
30
- }
31
-
32
- DEFAULT_FILTER_BLOCK = Object.new
156
+ dynamic: Filters::DynamicFilter,
157
+ }.freeze
33
158
 
34
159
  # @!visibility private
35
- def self.included(base)
36
- base.extend ClassMethods
37
- base.class_eval do
160
+ DEFAULT_FILTER_BLOCK = Object.new
38
161
 
39
- include Datagrid::Core
40
- include Datagrid::Filters::CompositeFilters
41
- class_attribute :filters_array, default: []
162
+ extend ActiveSupport::Concern
42
163
 
43
- end
164
+ # @!visibility private
165
+ included do
166
+ include Datagrid::Core
167
+ class_attribute :filters_array, default: []
44
168
  end
45
169
 
170
+ # Grid class methods related to filters
46
171
  module ClassMethods
47
-
48
- # Returns filter definition object by name
172
+ # @return [Datagrid::Filters::BaseFilter, nil] filter definition object by name
49
173
  def filter_by_name(attribute)
50
174
  if attribute.is_a?(Datagrid::Filters::BaseFilter)
51
175
  unless ancestors.include?(attribute.grid_class)
52
- raise "#{attribute.grid_class}##{attribute.name} filter doen't belong to #{self.class}"
176
+ raise ArgumentError, "#{attribute.grid_class}##{attribute.name} filter doen't belong to #{self.class}"
53
177
  end
178
+
54
179
  return attribute
55
180
  end
56
- self.filters.find do |filter|
181
+ filters.find do |filter|
57
182
  filter.name == attribute.to_sym
58
183
  end
59
184
  end
@@ -62,18 +187,20 @@ module Datagrid
62
187
  # This method automatically generates <tt>attr_accessor</tt> for filter name
63
188
  # and adds it to the list of datagrid attributes.
64
189
  #
65
- # Arguments:
66
- #
67
- # * <tt>name</tt> - filter name
68
- # * <tt>type</tt> - filter type that defines type case and GUI representation of a filter
69
- # * <tt>options</tt> - hash of options
70
- # * <tt>block</tt> - proc to apply the filter
190
+ # @param [Symbol] name filter name
191
+ # @param [Symbol] type filter type that defines type case and GUI representation of a filter
192
+ # @param [Hash] options hash of options
193
+ # @param [Proc] block proc to apply the filter
194
+ # @return [Datagrid::Filters::BaseFilter] Filter definition object
195
+ # @see https://github.com/bogdan/datagrid/wiki/Filters
71
196
  #
72
197
  # Available options:
73
198
  #
74
199
  # * <tt>:header</tt> - determines the header of the filter
75
- # * <tt>:default</tt> - the default filter value. Able to accept a <tt>Proc</tt> in case default should be recalculated
76
- # * <tt>:range</tt> - if true, filter can accept two values that are treated as a range that will be used for filtering
200
+ # * <tt>:default</tt> - the default filter value.
201
+ # Can be a <tt>Proc</tt> in case default should be recalculated.
202
+ # * <tt>:range</tt> - if true, filter can accept two values that are treated
203
+ # as a range that will be used for filtering.
77
204
  # Not all of the filter types support this option. Here are the list of types that do:
78
205
  # <tt>:integer</tt>, <tt>:float</tt>, <tt>:date</tt>, <tt>:datetime</tt>, <tt>:string</tt>
79
206
  # * <tt>:multiple</tt> - if true multiple values can be assigned to this filter.
@@ -82,9 +209,9 @@ module Datagrid
82
209
  # * <tt>:allow_nil</tt> - determines if the value can be nil
83
210
  # * <tt>:allow_blank</tt> - determines if the value can be blank
84
211
  # * <tt>:before</tt> - determines the position of this filter,
85
- # by adding it before the filter passed here (when using datagrid_form_for helper)
212
+ # by adding it before the filter passed here (when using datagrid_form_with helper)
86
213
  # * <tt>:after</tt> - determines the position of this filter,
87
- # by adding it after the filter passed here (when using datagrid_form_for helper)
214
+ # by adding it after the filter passed here (when using datagrid_form_with helper)
88
215
  # * <tt>:dummy</tt> - if true, this filter will not be applied automatically
89
216
  # and will be just displayed in form. In case you may want to apply it manually.
90
217
  # * <tt>:if</tt> - specify the condition when the filter can be dislayed and used.
@@ -94,29 +221,31 @@ module Datagrid
94
221
  # * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
95
222
  # Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
96
223
  # * <tt>:label_options</tt> - options passed when rendering html label tag attributes
97
- #
98
- # See: https://github.com/bogdan/datagrid/wiki/Filters for examples
99
224
  def filter(name, type = :default, **options, &block)
100
225
  klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
101
226
  raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
102
227
 
103
228
  position = Datagrid::Utils.extract_position_from_options(filters_array, options)
104
- filter = klass.new(self, name, options, &block)
229
+ filter = klass.new(self, name, **options, &block)
105
230
  filters_array.insert(position, filter)
106
231
 
107
232
  datagrid_attribute(name) do |value|
108
233
  filter.parse_values(value)
109
234
  end
235
+ filter
110
236
  end
111
237
 
238
+ # @!visibility private
112
239
  def default_filter
113
240
  DEFAULT_FILTER_BLOCK
114
241
  end
115
242
 
243
+ # @!visibility private
116
244
  def inspect
117
245
  "#{super}(#{filters_inspection})"
118
246
  end
119
247
 
248
+ # @return [Array<Datagrid::Filters::BaseFilter>] all defined filters
120
249
  def filters
121
250
  filters_array
122
251
  end
@@ -124,26 +253,27 @@ module Datagrid
124
253
  protected
125
254
 
126
255
  def inherited(child_class)
127
- super(child_class)
128
- child_class.filters_array = self.filters_array.clone
256
+ super
257
+ child_class.filters_array = filters_array.clone
129
258
  end
130
259
 
131
260
  def filters_inspection
132
261
  return "no filters" if filters.empty?
262
+
133
263
  filters.map do |filter|
134
264
  "#{filter.name}: #{filter.type}"
135
265
  end.join(", ")
136
266
  end
137
267
  end
138
268
 
139
-
140
269
  # @!visibility private
141
- def initialize(*args, &block)
270
+ def initialize(...)
142
271
  self.filters_array = self.class.filters_array.clone
143
- self.filters_array.each do |filter|
144
- self[filter.name] = filter.default(self)
272
+ filters_array.each do |filter|
273
+ value = filter.default(self)
274
+ self[filter.name] = value unless value.nil?
145
275
  end
146
- super(*args, &block)
276
+ super
147
277
  end
148
278
 
149
279
  # @!visibility private
@@ -151,68 +281,71 @@ module Datagrid
151
281
  apply_filters(super, filters)
152
282
  end
153
283
 
154
- # Returns filter value for given filter definition
284
+ # @return [Object] filter value for given filter definition
155
285
  def filter_value(filter)
156
286
  self[filter.name]
157
287
  end
158
288
 
159
- # Returns string representation of filter value
289
+ # @return [String] string representation of filter value
160
290
  def filter_value_as_string(name)
161
291
  filter = filter_by_name(name)
162
292
  value = filter_value(filter)
163
293
  if value.is_a?(Array)
164
- value.map {|v| filter.format(v) }.join(filter.separator)
294
+ value.map { |v| filter.format(v) }.join(filter.separator)
165
295
  else
166
296
  filter.format(value)
167
297
  end
168
298
  end
169
299
 
170
- # Returns filter object with the given name
300
+ # @return [Datagrid::Filters::BaseFilter, nil] filter object with the given name
171
301
  def filter_by_name(name)
172
302
  self.class.filter_by_name(name)
173
303
  end
174
304
 
175
- # Returns assets filtered only by specified filters
176
- # Allows partial filtering
305
+ # @return [Array<Object>] assets filtered only by specified filters
177
306
  def filter_by(*filters)
178
- apply_filters(scope, filters.map{|f| filter_by_name(f)})
307
+ apply_filters(scope, filters.map { |f| filter_by_name(f) })
179
308
  end
180
309
 
181
- # Returns select options for specific filter or filter name
182
- # If given filter doesn't support select options raises `ArgumentError`
310
+ # @return [Array] the select options for the filter
311
+ # @raise [ArgumentError] if the filter doesn't support select options
183
312
  def select_options(filter)
184
313
  find_select_filter(filter).select(self)
185
314
  end
186
315
 
187
- # Sets all options as selected for a filter that has options
316
+ # @return [void] sets all options as selected for a filter that has options
188
317
  def select_all(filter)
189
318
  filter = find_select_filter(filter)
190
319
  self[filter.name] = select_values(filter)
191
320
  end
192
321
 
193
- # Returns all values that can be set to a filter with select options
322
+ # @return [Array] all possible values for the filter
194
323
  def select_values(filter)
195
324
  find_select_filter(filter).select_values(self)
196
325
  end
197
326
 
198
- def default_filter
199
- self.class.default_filter
200
- end
201
-
202
- # Returns all currently enabled filters
327
+ # @return [Array<Datagrid::Filters::BaseFilter>] all currently enabled filters
203
328
  def filters
204
329
  self.class.filters.select do |filter|
205
330
  filter.enabled?(self)
206
331
  end
207
332
  end
208
333
 
334
+ # @!visibility private
335
+ def default_filter
336
+ self.class.default_filter
337
+ end
338
+
209
339
  protected
210
340
 
211
341
  def find_select_filter(filter)
212
342
  filter = filter_by_name(filter)
213
343
  unless filter.class.included_modules.include?(::Datagrid::Filters::SelectOptions)
214
- raise ::Datagrid::ArgumentError,
215
- "#{self.class.name}##{filter.name} with type #{FILTER_TYPES.invert[filter.class].inspect} can not have select options"
344
+ type = FILTER_TYPES.invert[filter.class].inspect
345
+ raise(
346
+ ::Datagrid::ArgumentError,
347
+ "#{self.class.name}##{filter.name} with type #{type} can not have select options",
348
+ )
216
349
  end
217
350
  filter
218
351
  end