rails_admin 3.3.0 → 3.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88dd830859396863dc21eab6dec1f7a63f1461e15b73a72affe62a9a869bf1c2
4
- data.tar.gz: 71fd4db63b36b2b74963811c83fb1daed9a58df33a5f5d23aa4491895217fa43
3
+ metadata.gz: a18178de7305b2be5286d22268d911c84952d779d46210548887cf220f5c052d
4
+ data.tar.gz: d0f6a162ca88c76b4be204608f5d265843c8bb59a55d93fe0b5fd65575e7c36e
5
5
  SHA512:
6
- metadata.gz: 162243c834a4170045a43debd41e8d87ba27c81130770243cbd659af4077f46e2c8557667638c40608de9d0f765cebfd415556f4fd610cd884968837a8d28fc6
7
- data.tar.gz: cec35b0c4b4ab71d967ac933b7eb15f51170742ce978996f913873c4f180d069bb680682eb658f571c4641ff351217d9f8c7744b998e5f3d8933636cb1b40f64
6
+ metadata.gz: f93d7e8d4cab0ac54b62db959da642a0a83267234c92f7394cb2eb2ad44e821804fe7bd11a0a34eeb090eec10265dbe6abd06b0d3ce17c8992525976af513ba8
7
+ data.tar.gz: 2abe7c0eaca1c5ea064408bf389d7e108df43808e6551418c25945578e1d4d611a799a786b8de851b99ce86010f2615aa36a64b5d3b259c32f704f1b6ce627b9
data/Gemfile CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'appraisal', '>= 2.0'
5
+ gem 'appraisal', '>= 2.0', require: false
6
6
  gem 'devise', '~> 4.7'
7
7
  gem 'net-smtp', require: false
8
8
  gem 'rails'
@@ -18,12 +18,13 @@ end
18
18
 
19
19
  group :test do
20
20
  gem 'cancancan', '~> 3.0'
21
- gem 'carrierwave', ['>= 2.0.0.rc', '< 3']
21
+ gem 'carrierwave', ['>= 2.2.1', '< 3']
22
22
  gem 'cuprite', '!= 0.15.1'
23
23
  gem 'database_cleaner-active_record', '>= 2.0', require: false
24
24
  gem 'dragonfly', '~> 1.0'
25
25
  gem 'factory_bot', '>= 4.2', '!= 6.4.5'
26
26
  gem 'generator_spec', '>= 0.8'
27
+ gem 'json', '< 3' # Workaround for json 3.0 quirks_mode removal
27
28
  gem 'kt-paperclip'
28
29
  gem 'launchy', '>= 2.2'
29
30
  gem 'mini_magick', '>= 3.4'
@@ -94,6 +94,17 @@ module RailsAdmin
94
94
  model_config.send(action).with(controller: self, view: view_context, object: @object).visible_fields
95
95
  end
96
96
 
97
+ # Memoized, as export renders through index, which switches @action
98
+ def serialization_schema
99
+ @serialization_schema ||= begin
100
+ section = %i[export show].include?(@action.key) ? @model_config.send(@action.key) : @model_config.list
101
+ RailsAdmin::SerializationSchema.new(
102
+ section.with(controller: self, view: view_context, object: @object || @abstract_model.model.new),
103
+ include_associations: @action.key == :export,
104
+ )
105
+ end
106
+ end
107
+
97
108
  def sanitize_params_for!(action, model_config = @model_config, target_params = params[@abstract_model.param_key])
98
109
  return unless target_params.present?
99
110
 
@@ -149,9 +149,10 @@ module RailsAdmin
149
149
  private
150
150
 
151
151
  def nested_field_association?(field, nested_in)
152
- field.inverse_of.presence && nested_in.presence && field.inverse_of == nested_in.name &&
153
- (@template.instance_variable_get(:@model_config).abstract_model == field.abstract_model ||
154
- field.name == nested_in.inverse_of)
152
+ nested_in.presence &&
153
+ (field.name == nested_in.inverse_of ||
154
+ (field.inverse_of.presence && field.inverse_of == nested_in.name &&
155
+ @template.instance_variable_get(:@model_config).abstract_model == field.abstract_model))
155
156
  end
156
157
  end
157
158
  end
@@ -12,6 +12,7 @@ module RailsAdmin
12
12
 
13
13
  def format
14
14
  imports = packager.import("rails_admin@#{RailsAdmin::Version.js}", from: 'jspm.io')
15
+ imports = imports[:imports] if imports.key?(:imports)
15
16
 
16
17
  # Use ESM compatible version to work around https://github.com/cljsjs/packages/issues/1579
17
18
  imports['@popperjs/core'].gsub!('lib/index.js', 'dist/esm/popper.js')
@@ -105,7 +105,7 @@ module RailsAdmin
105
105
  end
106
106
 
107
107
  def inverse_of
108
- options[:inverse_of].try :to_sym
108
+ options[:inverse_of].try(:to_sym) || as
109
109
  end
110
110
 
111
111
  def read_only?
@@ -25,6 +25,10 @@ module RailsAdmin
25
25
  model.all
26
26
  end
27
27
 
28
+ def none
29
+ model.none
30
+ end
31
+
28
32
  def first(options = {}, scope = nil)
29
33
  all(options, scope).first
30
34
  end
@@ -111,7 +111,7 @@ module RailsAdmin
111
111
  end
112
112
 
113
113
  def inverse_of
114
- association.inverse_of.try :to_sym
114
+ association.inverse_of.try(:to_sym) || as
115
115
  end
116
116
 
117
117
  def read_only?
@@ -39,6 +39,11 @@ module RailsAdmin
39
39
  model.scoped
40
40
  end
41
41
 
42
+ # Criteria#none is lost when merged into another criteria
43
+ def none
44
+ scoped.in(_id: [])
45
+ end
46
+
42
47
  def first(options = {}, scope = nil)
43
48
  all(options, scope).first
44
49
  end
@@ -19,7 +19,8 @@ module RailsAdmin
19
19
  format = params[:json] && :json || params[:csv] && :csv || params[:xml] && :xml
20
20
  if format
21
21
  request.format = format
22
- @schema = HashHelper.symbolize(params[:schema].slice(:except, :include, :methods, :only).permit!.to_h) if params[:schema] # to_json and to_xml expect symbols for keys AND values.
22
+ serialization_schema # built while @action is still export
23
+ @schema = serialization_schema.sanitize(params[:schema].slice(:include, :methods, :only).permit!.to_h) if params[:schema]
23
24
  @objects = list_entries(@model_config, :export)
24
25
  index
25
26
  else
@@ -56,7 +56,7 @@ module RailsAdmin
56
56
  @objects.collect { |object| {id: object.id.to_s, label: object.send(@model_config.object_label_method).to_s} }
57
57
  end
58
58
  else
59
- @objects.to_json(@schema)
59
+ @objects.to_json(@schema || serialization_schema.default)
60
60
  end
61
61
 
62
62
  if params[:send_data]
@@ -67,7 +67,7 @@ module RailsAdmin
67
67
  end
68
68
 
69
69
  format.xml do
70
- output = @objects.to_xml(@schema)
70
+ output = @objects.to_xml(@schema || serialization_schema.default)
71
71
  if params[:send_data]
72
72
  send_data output, filename: "#{params[:model_name]}_#{DateTime.now.strftime('%Y-%m-%d_%Hh%Mm%S')}.xml"
73
73
  else
@@ -21,7 +21,7 @@ module RailsAdmin
21
21
  register_instance_option :controller do
22
22
  proc do
23
23
  respond_to do |format|
24
- format.json { render json: @object }
24
+ format.json { render json: @object.to_json(serialization_schema.default) }
25
25
  format.html { render @action.template_name }
26
26
  end
27
27
  end
@@ -9,7 +9,7 @@ module RailsAdmin
9
9
  base.send :extend, ClassMethods
10
10
  end
11
11
 
12
- def has_option?(name) # rubocop:disable Naming/PredicateName
12
+ def has_option?(name) # rubocop:disable Naming/PredicatePrefix
13
13
  options = self.class.instance_variable_get('@config_options')
14
14
  options&.key?(name)
15
15
  end
@@ -44,7 +44,8 @@ module RailsAdmin
44
44
  def query(_action, abstract_model)
45
45
  @controller.send(:policy_scope, abstract_model.model.all)
46
46
  rescue ::Pundit::NotDefinedError
47
- abstract_model.model.all
47
+ # Fail closed: a missing policy scope must not be treated as "no restriction".
48
+ abstract_model.none
48
49
  end
49
50
 
50
51
  # This is called in the new/create actions to determine the initial attributes for new
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_admin/support/hash_helper'
4
+
5
+ module RailsAdmin
6
+ # The options passed to to_json/to_xml, limited to what a section exposes.
7
+ # It mirrors what the export form offers, as the form is what builds them.
8
+ class SerializationSchema
9
+ def initialize(section, include_associations:)
10
+ @section = section
11
+ @include_associations = include_associations
12
+ end
13
+
14
+ def default
15
+ sanitize(allowed)
16
+ end
17
+
18
+ # Anything not allowed is dropped, and `only` is always set, since leaving
19
+ # it out makes to_json/to_xml serialize every attribute.
20
+ def sanitize(requested)
21
+ requested = HashHelper.symbolize(requested)
22
+ schema = filter(requested, allowed)
23
+ if @include_associations && requested[:include].is_a?(Hash)
24
+ schema[:include] = requested[:include].each_with_object({}) do |(name, value), included|
25
+ next unless value.is_a?(Hash) && allowed[:include].key?(name)
26
+
27
+ included[name] = filter(value, allowed[:include][name])
28
+ end
29
+ end
30
+ schema
31
+ end
32
+
33
+ private
34
+
35
+ def allowed
36
+ @allowed ||= begin
37
+ fields = @section.visible_fields
38
+ names = field_names(fields.select { |f| !f.association? || f.association.polymorphic? })
39
+ if @include_associations
40
+ names[:include] = fields.select { |f| f.association? && !f.association.polymorphic? }.to_h do |field|
41
+ associated = field.associated_model_config.export.with(@section.bindings.merge(object: field.associated_model_config.abstract_model.model.new))
42
+ [field.name, field_names(associated.visible_fields.reject(&:association?))]
43
+ end
44
+ else
45
+ # The list shows these associations already, so their keys expose nothing more
46
+ names[:only].concat(fields.select { |f| f.association? && f.association.type == :belongs_to && !f.association.polymorphic? }.
47
+ flat_map { |f| Array(f.association.foreign_key) })
48
+ end
49
+ names
50
+ end
51
+ end
52
+
53
+ def field_names(fields)
54
+ fields.each_with_object({only: [], methods: []}) do |field, names|
55
+ list = field.virtual? ? names[:methods] : names[:only]
56
+ if field.association?
57
+ list << field.method_name.to_sym << field.association.foreign_type.to_sym
58
+ else
59
+ list << field.name
60
+ end
61
+ end
62
+ end
63
+
64
+ def filter(requested, permitted)
65
+ only = Array(requested[:only]) & permitted[:only]
66
+ # Mongoid serializes every attribute for an empty `only`
67
+ schema = {only: only.presence || [:__none__]}
68
+ schema[:methods] = Array(requested[:methods]) & permitted[:methods] if requested.key?(:methods)
69
+ schema
70
+ end
71
+ end
72
+ end
@@ -4,7 +4,7 @@ module RailsAdmin
4
4
  class Version
5
5
  MAJOR = 3
6
6
  MINOR = 3
7
- PATCH = 0
7
+ PATCH = 1
8
8
  PRE = nil
9
9
 
10
10
  class << self
data/lib/rails_admin.rb CHANGED
@@ -10,6 +10,7 @@ require 'rails_admin/extensions/pundit'
10
10
  require 'rails_admin/extensions/paper_trail'
11
11
  require 'rails_admin/support/csv_converter'
12
12
  require 'rails_admin/support/hash_helper'
13
+ require 'rails_admin/support/serialization_schema'
13
14
  require 'yaml'
14
15
 
15
16
  module RailsAdmin
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails_admin",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.",
5
5
  "homepage": "https://github.com/railsadminteam/rails_admin",
6
6
  "license": "MIT",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
@@ -9,10 +9,9 @@ authors:
9
9
  - Petteri Kaapa
10
10
  - Benoit Benezech
11
11
  - Mitsuhiro Shibuya
12
- autorequire:
13
12
  bindir: bin
14
13
  cert_chain: []
15
- date: 2024-12-08 00:00:00.000000000 Z
14
+ date: 1980-01-02 00:00:00.000000000 Z
16
15
  dependencies:
17
16
  - !ruby/object:Gem::Dependency
18
17
  name: activemodel-serializers-xml
@@ -216,7 +215,6 @@ files:
216
215
  - lib/rails_admin.rb
217
216
  - lib/rails_admin/abstract_model.rb
218
217
  - lib/rails_admin/adapters/active_record.rb
219
- - lib/rails_admin/adapters/active_record.rb.bak
220
218
  - lib/rails_admin/adapters/active_record/association.rb
221
219
  - lib/rails_admin/adapters/active_record/object_extension.rb
222
220
  - lib/rails_admin/adapters/active_record/property.rb
@@ -338,6 +336,7 @@ files:
338
336
  - lib/rails_admin/support/datetime.rb
339
337
  - lib/rails_admin/support/es_module_processor.rb
340
338
  - lib/rails_admin/support/hash_helper.rb
339
+ - lib/rails_admin/support/serialization_schema.rb
341
340
  - lib/rails_admin/version.rb
342
341
  - lib/tasks/rails_admin.rake
343
342
  - package.json
@@ -491,8 +490,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
491
490
  - !ruby/object:Gem::Version
492
491
  version: 1.8.11
493
492
  requirements: []
494
- rubygems_version: 3.4.10
495
- signing_key:
493
+ rubygems_version: 4.0.19
496
494
  specification_version: 4
497
495
  summary: Admin for Rails
498
496
  test_files: []
@@ -1,348 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_record'
4
- require 'rails_admin/adapters/active_record/association'
5
- require 'rails_admin/adapters/active_record/model_extension'
6
- require 'rails_admin/adapters/active_record/property'
7
-
8
- module RailsAdmin
9
- module Adapters
10
- module ActiveRecord
11
- DISABLED_COLUMN_TYPES = %i[tsvector blob binary spatial hstore geometry].freeze
12
-
13
- def model_with_extension
14
- @model_with_extension ||=
15
- begin
16
- klass = Class.new(model) do
17
- include ModelExtension
18
- end
19
- klass.instance_eval <<-RUBY, __FILE__, __LINE__+1
20
- def name
21
- "#{@model_name.to_s}"
22
- end
23
- RUBY
24
- klass
25
- end
26
- end
27
-
28
- def new(params = {})
29
- model_with_extension.new(params)
30
- end
31
-
32
- def get(id, scope = nil)
33
- scope = model_with_extension.merge(scope || scoped)
34
- scope.where(primary_key => id).first
35
- end
36
-
37
- def scoped
38
- model_with_extension.all
39
- end
40
-
41
- def first(options = {}, scope = nil)
42
- all(options, scope).first
43
- end
44
-
45
- def all(options = {}, scope = nil)
46
- scope = model_with_extension.merge(scope || scoped)
47
- scope = scope.includes(options[:include]) if options[:include]
48
- scope = scope.limit(options[:limit]) if options[:limit]
49
- scope = bulk_scope(scope, options) if options[:bulk_ids]
50
- scope = query_scope(scope, options[:query]) if options[:query]
51
- scope = filter_scope(scope, options[:filters]) if options[:filters]
52
- scope = scope.send(Kaminari.config.page_method_name, options[:page]).per(options[:per]) if options[:page] && options[:per]
53
- scope = sort_scope(scope, options) if options[:sort]
54
- scope
55
- end
56
-
57
- def count(options = {}, scope = nil)
58
- all(options.merge(limit: false, page: false), scope).count(:all)
59
- end
60
-
61
- def destroy(objects)
62
- Array.wrap(objects).each(&:destroy)
63
- end
64
-
65
- def associations
66
- model.reflect_on_all_associations.collect do |association|
67
- Association.new(association, model)
68
- end
69
- end
70
-
71
- def properties
72
- columns = model.columns.reject do |c|
73
- c.type.blank? ||
74
- DISABLED_COLUMN_TYPES.include?(c.type.to_sym) ||
75
- c.try(:array)
76
- end
77
- columns.collect do |property|
78
- Property.new(property, model)
79
- end
80
- end
81
-
82
- def base_class
83
- model.base_class
84
- end
85
-
86
- delegate :primary_key, :table_name, to: :model, prefix: false
87
-
88
- def quoted_table_name
89
- model.quoted_table_name
90
- end
91
-
92
- def quote_column_name(name)
93
- model.connection.quote_column_name(name)
94
- end
95
-
96
- def encoding
97
- adapter =
98
- if ::ActiveRecord::Base.respond_to?(:connection_db_config)
99
- ::ActiveRecord::Base.connection_db_config.configuration_hash[:adapter]
100
- else
101
- ::ActiveRecord::Base.connection_config[:adapter]
102
- end
103
- case adapter
104
- when 'postgresql'
105
- ::ActiveRecord::Base.connection.select_one("SELECT ''::text AS str;").values.first.encoding
106
- when 'mysql2'
107
- if RUBY_ENGINE == 'jruby'
108
- ::ActiveRecord::Base.connection.select_one("SELECT '' AS str;").values.first.encoding
109
- else
110
- ::ActiveRecord::Base.connection.raw_connection.encoding
111
- end
112
- when 'oracle_enhanced'
113
- ::ActiveRecord::Base.connection.select_one('SELECT dummy FROM DUAL').values.first.encoding
114
- else
115
- ::ActiveRecord::Base.connection.select_one("SELECT '' AS str;").values.first.encoding
116
- end
117
- end
118
-
119
- def embedded?
120
- false
121
- end
122
-
123
- def cyclic?
124
- false
125
- end
126
-
127
- def adapter_supports_joins?
128
- true
129
- end
130
-
131
- private
132
-
133
- def bulk_scope(scope, options)
134
- scope.where(primary_key => options[:bulk_ids])
135
- end
136
-
137
- def sort_scope(scope, options)
138
- direction = options[:sort_reverse] ? :asc : :desc
139
- case options[:sort]
140
- when String, Symbol
141
- scope.reorder("#{options[:sort]} #{direction}")
142
- when Array
143
- scope.reorder(options[:sort].zip(Array.new(options[:sort].size) { direction }).to_h)
144
- when Hash
145
- scope.reorder(options[:sort].map { |table_name, column| "#{table_name}.#{column}" }.
146
- zip(Array.new(options[:sort].size) { direction }).to_h)
147
- else
148
- raise ArgumentError.new("Unsupported sort value: #{options[:sort]}")
149
- end
150
- end
151
-
152
- class WhereBuilder
153
- def initialize(scope)
154
- @statements = []
155
- @values = []
156
- @tables = []
157
- @scope = scope
158
- end
159
-
160
- def add(field, value, operator)
161
- field.searchable_columns.flatten.each do |column_infos|
162
- statement, value1, value2 = StatementBuilder.new(column_infos[:column], column_infos[:type], value, operator, @scope.connection.adapter_name).to_statement
163
- @statements << statement if statement.present?
164
- @values << value1 unless value1.nil?
165
- @values << value2 unless value2.nil?
166
- table, column = column_infos[:column].split('.')
167
- @tables.push(table) if column
168
- end
169
- end
170
-
171
- def build
172
- scope = @scope.where(@statements.join(' OR '), *@values)
173
- scope = scope.references(*@tables.uniq) if @tables.any?
174
- scope
175
- end
176
- end
177
-
178
- def query_scope(scope, query, fields = config.list.fields.select(&:queryable?))
179
- if config.list.search_by
180
- scope.send(config.list.search_by, query)
181
- else
182
- wb = WhereBuilder.new(scope)
183
- fields.each do |field|
184
- value = parse_field_value(field, query)
185
- wb.add(field, value, field.search_operator)
186
- end
187
- # OR all query statements
188
- wb.build
189
- end
190
- end
191
-
192
- # filters example => {"string_field"=>{"0055"=>{"o"=>"like", "v"=>"test_value"}}, ...}
193
- # "0055" is the filter index, no use here. o is the operator, v the value
194
- def filter_scope(scope, filters, fields = config.list.fields.select(&:filterable?))
195
- filters.each_pair do |field_name, filters_dump|
196
- filters_dump.each_value do |filter_dump|
197
- wb = WhereBuilder.new(scope)
198
- field = fields.detect { |f| f.name.to_s == field_name }
199
- value = parse_field_value(field, filter_dump[:v])
200
-
201
- wb.add(field, value, (filter_dump[:o] || RailsAdmin::Config.default_search_operator))
202
- # AND current filter statements to other filter statements
203
- scope = wb.build
204
- end
205
- end
206
- scope
207
- end
208
-
209
- def build_statement(column, type, value, operator)
210
- StatementBuilder.new(column, type, value, operator, model.connection.adapter_name).to_statement
211
- end
212
-
213
- class StatementBuilder < RailsAdmin::AbstractModel::StatementBuilder
214
- def initialize(column, type, value, operator, adapter_name)
215
- super column, type, value, operator
216
- @adapter_name = adapter_name
217
- end
218
-
219
- protected
220
-
221
- def unary_operators
222
- case @type
223
- when :boolean
224
- boolean_unary_operators
225
- when :uuid
226
- uuid_unary_operators
227
- when :integer, :decimal, :float
228
- numeric_unary_operators
229
- else
230
- generic_unary_operators
231
- end
232
- end
233
-
234
- private
235
-
236
- def generic_unary_operators
237
- {
238
- '_blank' => ["(#{@column} IS NULL OR #{@column} = '')"],
239
- '_present' => ["(#{@column} IS NOT NULL AND #{@column} != '')"],
240
- '_null' => ["(#{@column} IS NULL)"],
241
- '_not_null' => ["(#{@column} IS NOT NULL)"],
242
- '_empty' => ["(#{@column} = '')"],
243
- '_not_empty' => ["(#{@column} != '')"],
244
- }
245
- end
246
-
247
- def boolean_unary_operators
248
- generic_unary_operators.merge(
249
- '_blank' => ["(#{@column} IS NULL)"],
250
- '_empty' => ["(#{@column} IS NULL)"],
251
- '_present' => ["(#{@column} IS NOT NULL)"],
252
- '_not_empty' => ["(#{@column} IS NOT NULL)"],
253
- )
254
- end
255
- alias_method :numeric_unary_operators, :boolean_unary_operators
256
- alias_method :uuid_unary_operators, :boolean_unary_operators
257
-
258
- def range_filter(min, max)
259
- if min && max && min == max
260
- ["(#{@column} = ?)", min]
261
- elsif min && max
262
- ["(#{@column} BETWEEN ? AND ?)", min, max]
263
- elsif min
264
- ["(#{@column} >= ?)", min]
265
- elsif max
266
- ["(#{@column} <= ?)", max]
267
- end
268
- end
269
-
270
- def build_statement_for_type
271
- case @type
272
- when :boolean then build_statement_for_boolean
273
- when :integer, :decimal, :float then build_statement_for_integer_decimal_or_float
274
- when :string, :text, :citext then build_statement_for_string_or_text
275
- when :enum then build_statement_for_enum
276
- when :belongs_to_association then build_statement_for_belongs_to_association
277
- when :uuid then build_statement_for_uuid
278
- end
279
- end
280
-
281
- def build_statement_for_boolean
282
- case @value
283
- when 'false', 'f', '0'
284
- ["(#{@column} IS NULL OR #{@column} = ?)", false]
285
- when 'true', 't', '1'
286
- ["(#{@column} = ?)", true]
287
- end
288
- end
289
-
290
- def column_for_value(value)
291
- ["(#{@column} = ?)", value]
292
- end
293
-
294
- def build_statement_for_belongs_to_association
295
- return if @value.blank?
296
-
297
- ["(#{@column} = ?)", @value.to_i] if @value.to_i.to_s == @value
298
- end
299
-
300
- def build_statement_for_string_or_text
301
- return if @value.blank?
302
-
303
- return ["(#{@column} = ?)", @value] if ['is', '='].include?(@operator)
304
-
305
- @value = @value.mb_chars.downcase unless %w[postgresql postgis].include? ar_adapter
306
-
307
- @value =
308
- case @operator
309
- when 'default', 'like', 'not_like'
310
- "%#{@value}%"
311
- when 'starts_with'
312
- "#{@value}%"
313
- when 'ends_with'
314
- "%#{@value}"
315
- else
316
- return
317
- end
318
-
319
- if %w[postgresql postgis].include? ar_adapter
320
- if @operator == 'not_like'
321
- ["(#{@column} NOT ILIKE ?)", @value]
322
- else
323
- ["(#{@column} ILIKE ?)", @value]
324
- end
325
- elsif @operator == 'not_like'
326
- ["(LOWER(#{@column}) NOT LIKE ?)", @value]
327
- else
328
- ["(LOWER(#{@column}) LIKE ?)", @value]
329
- end
330
- end
331
-
332
- def build_statement_for_enum
333
- return if @value.blank?
334
-
335
- ["(#{@column} IN (?))", Array.wrap(@value)]
336
- end
337
-
338
- def build_statement_for_uuid
339
- column_for_value(@value) if /\A[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}\z/.match?(@value.to_s)
340
- end
341
-
342
- def ar_adapter
343
- @adapter_name.downcase
344
- end
345
- end
346
- end
347
- end
348
- end