rails_admin 3.1.4 → 3.3.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.
- checksums.yaml +4 -4
- data/Gemfile +19 -14
- data/README.md +2 -2
- data/app/assets/javascripts/rails_admin/application.js.erb +3 -2
- data/app/assets/stylesheets/rails_admin/application.scss.erb +1 -1
- data/app/controllers/rails_admin/main_controller.rb +5 -1
- data/app/helpers/rails_admin/application_helper.rb +4 -0
- data/app/helpers/rails_admin/form_builder.rb +2 -2
- data/app/helpers/rails_admin/main_helper.rb +1 -1
- data/app/views/layouts/rails_admin/_head.html.erb +8 -5
- data/app/views/rails_admin/main/_form_boolean.html.erb +2 -2
- data/app/views/rails_admin/main/_form_filtering_multiselect.html.erb +5 -35
- data/app/views/rails_admin/main/_form_filtering_select.html.erb +6 -18
- data/app/views/rails_admin/main/_form_nested_many.html.erb +1 -1
- data/app/views/rails_admin/main/_form_nested_one.html.erb +1 -1
- data/app/views/rails_admin/main/_form_polymorphic_association.html.erb +12 -21
- data/app/views/rails_admin/main/delete.html.erb +1 -1
- data/config/initializers/active_record_extensions.rb +0 -23
- data/lib/generators/rails_admin/importmap_formatter.rb +1 -1
- data/lib/generators/rails_admin/install_generator.rb +13 -1
- data/lib/generators/rails_admin/templates/rails_admin.vite.js +2 -0
- data/lib/rails_admin/abstract_model.rb +18 -7
- data/lib/rails_admin/adapters/active_record/association.rb +25 -8
- data/lib/rails_admin/adapters/active_record/object_extension.rb +0 -18
- data/lib/rails_admin/adapters/active_record.rb +51 -5
- data/lib/rails_admin/adapters/mongoid/association.rb +1 -1
- data/lib/rails_admin/adapters/mongoid/object_extension.rb +0 -5
- data/lib/rails_admin/adapters/mongoid.rb +6 -3
- data/lib/rails_admin/config/actions/index.rb +5 -3
- data/lib/rails_admin/config/fields/association.rb +41 -2
- data/lib/rails_admin/config/fields/base.rb +4 -4
- data/lib/rails_admin/config/fields/collection_association.rb +90 -0
- data/lib/rails_admin/config/fields/singular_association.rb +59 -0
- data/lib/rails_admin/config/fields/types/active_storage.rb +12 -7
- data/lib/rails_admin/config/fields/types/all.rb +0 -1
- data/lib/rails_admin/config/fields/types/belongs_to_association.rb +17 -20
- data/lib/rails_admin/config/fields/types/dragonfly.rb +0 -1
- data/lib/rails_admin/config/fields/types/file_upload.rb +7 -1
- data/lib/rails_admin/config/fields/types/has_and_belongs_to_many_association.rb +2 -2
- data/lib/rails_admin/config/fields/types/has_many_association.rb +2 -24
- data/lib/rails_admin/config/fields/types/has_one_association.rb +12 -22
- data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +13 -8
- data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +7 -1
- data/lib/rails_admin/config/fields/types/polymorphic_association.rb +32 -9
- data/lib/rails_admin/config.rb +5 -0
- data/lib/rails_admin/engine.rb +5 -0
- data/lib/rails_admin/extensions/url_for_extension.rb +15 -0
- data/lib/rails_admin/support/composite_keys_serializer.rb +15 -0
- data/lib/rails_admin/support/datetime.rb +1 -0
- data/lib/rails_admin/version.rb +2 -2
- data/package.json +2 -2
- data/src/rails_admin/abstract-select.js +30 -0
- data/src/rails_admin/base.js +4 -1
- data/src/rails_admin/filtering-multiselect.js +2 -4
- data/src/rails_admin/filtering-select.js +2 -4
- metadata +39 -15
- data/lib/rails_admin/adapters/composite_primary_keys/association.rb +0 -45
- data/lib/rails_admin/adapters/composite_primary_keys.rb +0 -40
- data/lib/rails_admin/config/fields/types/composite_keys_belongs_to_association.rb +0 -31
@@ -15,7 +15,7 @@ module RailsAdmin
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def get(id, scope = scoped)
|
18
|
-
object = scope
|
18
|
+
object = primary_key_scope(scope, id).first
|
19
19
|
return unless object
|
20
20
|
|
21
21
|
object.extend(ObjectExtension)
|
@@ -72,6 +72,14 @@ module RailsAdmin
|
|
72
72
|
|
73
73
|
delegate :primary_key, :table_name, to: :model, prefix: false
|
74
74
|
|
75
|
+
def quoted_table_name
|
76
|
+
model.quoted_table_name
|
77
|
+
end
|
78
|
+
|
79
|
+
def quote_column_name(name)
|
80
|
+
model.connection.quote_column_name(name)
|
81
|
+
end
|
82
|
+
|
75
83
|
def encoding
|
76
84
|
adapter =
|
77
85
|
if ::ActiveRecord::Base.respond_to?(:connection_db_config)
|
@@ -107,10 +115,42 @@ module RailsAdmin
|
|
107
115
|
true
|
108
116
|
end
|
109
117
|
|
118
|
+
def format_id(id)
|
119
|
+
if primary_key.is_a? Array
|
120
|
+
RailsAdmin.config.composite_keys_serializer.serialize(id)
|
121
|
+
else
|
122
|
+
id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def parse_id(id)
|
127
|
+
if primary_key.is_a?(Array)
|
128
|
+
ids = RailsAdmin.config.composite_keys_serializer.deserialize(id)
|
129
|
+
primary_key.each_with_index do |key, i|
|
130
|
+
ids[i] = model.type_for_attribute(key).cast(ids[i])
|
131
|
+
end
|
132
|
+
ids
|
133
|
+
else
|
134
|
+
id
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
110
138
|
private
|
111
139
|
|
140
|
+
def primary_key_scope(scope, id)
|
141
|
+
if primary_key.is_a? Array
|
142
|
+
scope.where(primary_key.zip(parse_id(id)).to_h)
|
143
|
+
else
|
144
|
+
scope.where(primary_key => id)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
112
148
|
def bulk_scope(scope, options)
|
113
|
-
|
149
|
+
if primary_key.is_a? Array
|
150
|
+
options[:bulk_ids].map { |id| primary_key_scope(scope, id) }.reduce(&:or)
|
151
|
+
else
|
152
|
+
scope.where(primary_key => options[:bulk_ids])
|
153
|
+
end
|
114
154
|
end
|
115
155
|
|
116
156
|
def sort_scope(scope, options)
|
@@ -201,6 +241,8 @@ module RailsAdmin
|
|
201
241
|
case @type
|
202
242
|
when :boolean
|
203
243
|
boolean_unary_operators
|
244
|
+
when :uuid
|
245
|
+
uuid_unary_operators
|
204
246
|
when :integer, :decimal, :float
|
205
247
|
numeric_unary_operators
|
206
248
|
else
|
@@ -230,6 +272,7 @@ module RailsAdmin
|
|
230
272
|
)
|
231
273
|
end
|
232
274
|
alias_method :numeric_unary_operators, :boolean_unary_operators
|
275
|
+
alias_method :uuid_unary_operators, :boolean_unary_operators
|
233
276
|
|
234
277
|
def range_filter(min, max)
|
235
278
|
if min && max && min == max
|
@@ -255,9 +298,12 @@ module RailsAdmin
|
|
255
298
|
end
|
256
299
|
|
257
300
|
def build_statement_for_boolean
|
258
|
-
|
259
|
-
|
260
|
-
|
301
|
+
case @value
|
302
|
+
when 'false', 'f', '0'
|
303
|
+
["(#{@column} IS NULL OR #{@column} = ?)", false]
|
304
|
+
when 'true', 't', '1'
|
305
|
+
["(#{@column} = ?)", true]
|
306
|
+
end
|
261
307
|
end
|
262
308
|
|
263
309
|
def column_for_value(value)
|
@@ -46,7 +46,7 @@ module RailsAdmin
|
|
46
46
|
|
47
47
|
def klass
|
48
48
|
if polymorphic? && %i[referenced_in belongs_to].include?(macro)
|
49
|
-
polymorphic_parents(:mongoid,
|
49
|
+
polymorphic_parents(:mongoid, association.inverse_class_name, name) || []
|
50
50
|
else
|
51
51
|
association.klass
|
52
52
|
end
|
@@ -251,9 +251,12 @@ module RailsAdmin
|
|
251
251
|
end
|
252
252
|
|
253
253
|
def build_statement_for_boolean
|
254
|
-
|
255
|
-
|
256
|
-
|
254
|
+
case @value
|
255
|
+
when 'false', 'f', '0'
|
256
|
+
{@column => false}
|
257
|
+
when 'true', 't', '1'
|
258
|
+
{@column => true}
|
259
|
+
end
|
257
260
|
end
|
258
261
|
|
259
262
|
def column_for_value(value)
|
@@ -50,9 +50,11 @@ module RailsAdmin
|
|
50
50
|
format.json do
|
51
51
|
output =
|
52
52
|
if params[:compact]
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
if @association
|
54
|
+
@association.collection(@objects).collect { |(label, id)| {id: id, label: label} }
|
55
|
+
else
|
56
|
+
@objects.collect { |object| {id: object.id.to_s, label: object.send(@model_config.object_label_method).to_s} }
|
57
|
+
end
|
56
58
|
else
|
57
59
|
@objects.to_json(@schema)
|
58
60
|
end
|
@@ -13,7 +13,7 @@ module RailsAdmin
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def method_name
|
16
|
-
association.key_accessor
|
16
|
+
nested_form ? :"#{name}_attributes" : association.key_accessor
|
17
17
|
end
|
18
18
|
|
19
19
|
register_instance_option :pretty_value do
|
@@ -56,7 +56,30 @@ module RailsAdmin
|
|
56
56
|
# preload entire associated collection (per associated_collection_scope) on load
|
57
57
|
# Be sure to set limit in associated_collection_scope if set is large
|
58
58
|
register_instance_option :associated_collection_cache_all do
|
59
|
-
@associated_collection_cache_all ||= (associated_model_config.abstract_model.count < associated_model_limit)
|
59
|
+
@associated_collection_cache_all ||= dynamically_scope_by.blank? && (associated_model_config.abstract_model.count < associated_model_limit)
|
60
|
+
end
|
61
|
+
|
62
|
+
# client-side dynamic scoping
|
63
|
+
register_instance_option :dynamically_scope_by do
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
# parses #dynamically_scope_by and returns a Hash in the form of
|
68
|
+
# {[form field name in this model]: [field name in the associated model]}
|
69
|
+
def dynamic_scope_relationships
|
70
|
+
@dynamic_scope_relationships ||=
|
71
|
+
Array.wrap(dynamically_scope_by).flat_map do |field|
|
72
|
+
field.is_a?(Hash) ? field.to_a : [[field, field]]
|
73
|
+
end.map do |field_name, target_name| # rubocop:disable Style/MultilineBlockChain
|
74
|
+
field = section.fields.detect { |f| f.name == field_name }
|
75
|
+
raise "Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{abstract_model.model_name}'" unless field
|
76
|
+
|
77
|
+
target_field = associated_model_config.list.fields.detect { |f| f.name == target_name }
|
78
|
+
raise "Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{associated_model_config.abstract_model.model_name}'" unless target_field
|
79
|
+
raise "Field '#{field_name}' in '#{associated_model_config.abstract_model.model_name}' can't be used for dynamic scoping because it's not filterable" unless target_field.filterable
|
80
|
+
|
81
|
+
[field.method_name, target_name]
|
82
|
+
end.to_h
|
60
83
|
end
|
61
84
|
|
62
85
|
# determines whether association's elements can be removed
|
@@ -111,6 +134,12 @@ module RailsAdmin
|
|
111
134
|
bindings[:object].send(association.name)
|
112
135
|
end
|
113
136
|
|
137
|
+
# Returns collection of all selectable records
|
138
|
+
def collection(scope = nil)
|
139
|
+
(scope || bindings[:controller].list_entries(associated_model_config, :index, associated_collection_scope, false)).
|
140
|
+
map { |o| [o.send(associated_object_label_method), format_key(o.send(associated_primary_key)).to_s] }
|
141
|
+
end
|
142
|
+
|
114
143
|
# has many?
|
115
144
|
def multiple?
|
116
145
|
true
|
@@ -123,6 +152,16 @@ module RailsAdmin
|
|
123
152
|
def associated_model_limit
|
124
153
|
RailsAdmin.config.default_associated_collection_limit
|
125
154
|
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def format_key(key)
|
159
|
+
if key.is_a?(Array)
|
160
|
+
RailsAdmin.config.composite_keys_serializer.serialize(key)
|
161
|
+
else
|
162
|
+
key
|
163
|
+
end
|
164
|
+
end
|
126
165
|
end
|
127
166
|
end
|
128
167
|
end
|
@@ -62,15 +62,15 @@ module RailsAdmin
|
|
62
62
|
|
63
63
|
def sort_column
|
64
64
|
if sortable == true
|
65
|
-
"#{abstract_model.
|
65
|
+
"#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(name)}"
|
66
66
|
elsif (sortable.is_a?(String) || sortable.is_a?(Symbol)) && sortable.to_s.include?('.') # just provide sortable, don't do anything smart
|
67
67
|
sortable
|
68
68
|
elsif sortable.is_a?(Hash) # just join sortable hash, don't do anything smart
|
69
69
|
"#{sortable.keys.first}.#{sortable.values.first}"
|
70
|
-
elsif association # use column on target table
|
71
|
-
"#{associated_model_config.abstract_model.
|
70
|
+
elsif association? # use column on target table
|
71
|
+
"#{associated_model_config.abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}"
|
72
72
|
else # use described column in the field conf.
|
73
|
-
"#{abstract_model.
|
73
|
+
"#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}"
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_admin/config/fields/association'
|
4
|
+
|
5
|
+
module RailsAdmin
|
6
|
+
module Config
|
7
|
+
module Fields
|
8
|
+
class CollectionAssociation < Association
|
9
|
+
# orderable associated objects
|
10
|
+
register_instance_option :orderable do
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
register_instance_option :partial do
|
15
|
+
nested_form ? :form_nested_many : :form_filtering_multiselect
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection(scope = nil)
|
19
|
+
if scope
|
20
|
+
super
|
21
|
+
elsif associated_collection_cache_all
|
22
|
+
selected = selected_ids
|
23
|
+
i = 0
|
24
|
+
super.sort_by { |a| [selected.index(a[1]) || selected.size, i += 1] }
|
25
|
+
else
|
26
|
+
value.map { |o| [o.send(associated_object_label_method), format_key(o.send(associated_primary_key))] }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def associated_prepopulate_params
|
31
|
+
{associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
|
32
|
+
end
|
33
|
+
|
34
|
+
def multiple?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def selected_ids
|
39
|
+
value.map { |s| format_key(s.send(associated_primary_key)).to_s }
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_input(params)
|
43
|
+
return unless associated_model_config.abstract_model.primary_key.is_a?(Array)
|
44
|
+
|
45
|
+
if nested_form
|
46
|
+
params[method_name].each_value do |value|
|
47
|
+
value[:id] = associated_model_config.abstract_model.parse_id(value[:id])
|
48
|
+
end
|
49
|
+
elsif params[method_name].is_a?(Array)
|
50
|
+
params[method_name] = params[method_name].map { |key| associated_model_config.abstract_model.parse_id(key) if key.present? }.compact
|
51
|
+
if params[method_name].empty?
|
52
|
+
# Workaround for Arel::Visitors::UnsupportedVisitError in #ids_writer, until https://github.com/rails/rails/pull/51116 is in place
|
53
|
+
params.delete(method_name)
|
54
|
+
params[name] = []
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def form_default_value
|
60
|
+
(default_value if bindings[:object].new_record? && value.empty?)
|
61
|
+
end
|
62
|
+
|
63
|
+
def form_value
|
64
|
+
form_default_value.nil? ? selected_ids : form_default_value
|
65
|
+
end
|
66
|
+
|
67
|
+
def widget_options
|
68
|
+
{
|
69
|
+
xhr: !associated_collection_cache_all,
|
70
|
+
'edit-url': (inline_edit && bindings[:view].authorized?(:edit, associated_model_config.abstract_model) ? bindings[:view].edit_path(model_name: associated_model_config.abstract_model.to_param, id: '__ID__') : ''),
|
71
|
+
remote_source: bindings[:view].index_path(associated_model_config.abstract_model, source_object_id: abstract_model.format_id(bindings[:object].id), source_abstract_model: abstract_model.to_param, associated_collection: name, current_action: bindings[:view].current_action, compact: true),
|
72
|
+
scopeBy: dynamic_scope_relationships,
|
73
|
+
sortable: !!orderable,
|
74
|
+
removable: !!removable,
|
75
|
+
cacheAll: !!associated_collection_cache_all,
|
76
|
+
regional: {
|
77
|
+
add: ::I18n.t('admin.misc.add_new'),
|
78
|
+
chooseAll: ::I18n.t('admin.misc.chose_all'),
|
79
|
+
clearAll: ::I18n.t('admin.misc.clear_all'),
|
80
|
+
down: ::I18n.t('admin.misc.down'),
|
81
|
+
remove: ::I18n.t('admin.misc.remove'),
|
82
|
+
search: ::I18n.t('admin.misc.search'),
|
83
|
+
up: ::I18n.t('admin.misc.up'),
|
84
|
+
},
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_admin/config/fields/association'
|
4
|
+
|
5
|
+
module RailsAdmin
|
6
|
+
module Config
|
7
|
+
module Fields
|
8
|
+
class SingularAssociation < Association
|
9
|
+
register_instance_option :filter_operators do
|
10
|
+
%w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])
|
11
|
+
end
|
12
|
+
|
13
|
+
register_instance_option :formatted_value do
|
14
|
+
(o = value) && o.send(associated_model_config.object_label_method)
|
15
|
+
end
|
16
|
+
|
17
|
+
register_instance_option :partial do
|
18
|
+
nested_form ? :form_nested_one : :form_filtering_select
|
19
|
+
end
|
20
|
+
|
21
|
+
def collection(scope = nil)
|
22
|
+
if associated_collection_cache_all || scope
|
23
|
+
super
|
24
|
+
else
|
25
|
+
[[formatted_value, selected_id]]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def multiple?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def selected_id
|
34
|
+
raise NoMethodError # abstract
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_input(params)
|
38
|
+
return unless nested_form && params[method_name].try(:[], :id).present?
|
39
|
+
|
40
|
+
ids = associated_model_config.abstract_model.parse_id(params[method_name][:id])
|
41
|
+
ids = ids.to_composite_keys.to_s if ids.respond_to?(:to_composite_keys)
|
42
|
+
params[method_name][:id] = ids
|
43
|
+
end
|
44
|
+
|
45
|
+
def form_value
|
46
|
+
form_default_value.nil? ? selected_id : form_default_value
|
47
|
+
end
|
48
|
+
|
49
|
+
def widget_options
|
50
|
+
{
|
51
|
+
xhr: !associated_collection_cache_all,
|
52
|
+
remote_source: bindings[:view].index_path(associated_model_config.abstract_model, source_object_id: abstract_model.format_id(bindings[:object].id), source_abstract_model: abstract_model.to_param, associated_collection: name, current_action: bindings[:view].current_action, compact: true),
|
53
|
+
scopeBy: dynamic_scope_relationships,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -18,10 +18,7 @@ module RailsAdmin
|
|
18
18
|
end
|
19
19
|
|
20
20
|
register_instance_option :image? do
|
21
|
-
|
22
|
-
mime_type = Mime::Type.lookup_by_extension(value.filename.extension_without_delimiter)
|
23
|
-
mime_type.to_s.match?(/^image/)
|
24
|
-
end
|
21
|
+
value && (value.representable? || value.content_type.match?(/^image/))
|
25
22
|
end
|
26
23
|
|
27
24
|
register_instance_option :eager_load do
|
@@ -40,14 +37,22 @@ module RailsAdmin
|
|
40
37
|
)
|
41
38
|
end
|
42
39
|
|
40
|
+
register_instance_option :searchable do
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
register_instance_option :sortable do
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
43
48
|
def resource_url(thumb = false)
|
44
49
|
return nil unless value
|
45
50
|
|
46
|
-
if thumb && value.
|
51
|
+
if thumb && value.representable?
|
47
52
|
thumb = thumb_method if thumb == true
|
48
|
-
|
53
|
+
representation = value.representation(thumb)
|
49
54
|
Rails.application.routes.url_helpers.rails_blob_representation_path(
|
50
|
-
|
55
|
+
representation.blob.signed_id, representation.variation.key, representation.blob.filename, only_path: true
|
51
56
|
)
|
52
57
|
else
|
53
58
|
Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
|
@@ -6,7 +6,6 @@ require 'rails_admin/config/fields/types/active_storage'
|
|
6
6
|
require 'rails_admin/config/fields/types/belongs_to_association'
|
7
7
|
require 'rails_admin/config/fields/types/boolean'
|
8
8
|
require 'rails_admin/config/fields/types/bson_object_id'
|
9
|
-
require 'rails_admin/config/fields/types/composite_keys_belongs_to_association'
|
10
9
|
require 'rails_admin/config/fields/types/date'
|
11
10
|
require 'rails_admin/config/fields/types/datetime'
|
12
11
|
require 'rails_admin/config/fields/types/decimal'
|
@@ -1,22 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rails_admin/config/fields/
|
3
|
+
require 'rails_admin/config/fields/singular_association'
|
4
4
|
|
5
5
|
module RailsAdmin
|
6
6
|
module Config
|
7
7
|
module Fields
|
8
8
|
module Types
|
9
|
-
class BelongsToAssociation < RailsAdmin::Config::Fields::
|
9
|
+
class BelongsToAssociation < RailsAdmin::Config::Fields::SingularAssociation
|
10
10
|
RailsAdmin::Config::Fields::Types.register(self)
|
11
11
|
|
12
|
-
register_instance_option :filter_operators do
|
13
|
-
%w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])
|
14
|
-
end
|
15
|
-
|
16
|
-
register_instance_option :formatted_value do
|
17
|
-
(o = value) && o.send(associated_model_config.object_label_method)
|
18
|
-
end
|
19
|
-
|
20
12
|
register_instance_option :sortable do
|
21
13
|
@sortable ||= abstract_model.adapter_supports_joins? && associated_model_config.abstract_model.properties.collect(&:name).include?(associated_model_config.object_label_method) ? associated_model_config.object_label_method : {abstract_model.table_name => method_name}
|
22
14
|
end
|
@@ -25,24 +17,29 @@ module RailsAdmin
|
|
25
17
|
@searchable ||= associated_model_config.abstract_model.properties.collect(&:name).include?(associated_model_config.object_label_method) ? [associated_model_config.object_label_method, {abstract_model.model => method_name}] : {abstract_model.model => method_name}
|
26
18
|
end
|
27
19
|
|
28
|
-
register_instance_option :partial do
|
29
|
-
nested_form ? :form_nested_one : :form_filtering_select
|
30
|
-
end
|
31
|
-
|
32
20
|
register_instance_option :eager_load do
|
33
21
|
true
|
34
22
|
end
|
35
23
|
|
36
|
-
|
37
|
-
|
24
|
+
register_instance_option :allowed_methods do
|
25
|
+
nested_form ? [method_name] : Array(association.foreign_key)
|
38
26
|
end
|
39
27
|
|
40
|
-
def
|
41
|
-
|
28
|
+
def selected_id
|
29
|
+
if association.foreign_key.is_a?(Array)
|
30
|
+
format_key(association.foreign_key.map { |attribute| bindings[:object].safe_send(attribute) })
|
31
|
+
else
|
32
|
+
bindings[:object].safe_send(association.key_accessor)
|
33
|
+
end
|
42
34
|
end
|
43
35
|
|
44
|
-
def
|
45
|
-
|
36
|
+
def parse_input(params)
|
37
|
+
return super if nested_form
|
38
|
+
return unless params[method_name].present? && association.foreign_key.is_a?(Array)
|
39
|
+
|
40
|
+
association.foreign_key.zip(RailsAdmin.config.composite_keys_serializer.deserialize(params.delete(method_name))).each do |key, value|
|
41
|
+
params[key] = value
|
42
|
+
end
|
46
43
|
end
|
47
44
|
end
|
48
45
|
end
|
@@ -12,7 +12,6 @@ module RailsAdmin
|
|
12
12
|
RailsAdmin::Config::Fields::Types.register(self)
|
13
13
|
|
14
14
|
register_instance_option :image? do
|
15
|
-
false unless value
|
16
15
|
if abstract_model.model.new.respond_to?("#{name}_name")
|
17
16
|
mime_type = Mime::Type.lookup_by_extension(bindings[:object].send("#{name}_name").to_s.split('.').last)
|
18
17
|
mime_type.to_s.match?(/^image/)
|
@@ -52,7 +52,7 @@ module RailsAdmin
|
|
52
52
|
end
|
53
53
|
|
54
54
|
register_instance_option :image? do
|
55
|
-
mime_type = Mime::Type.lookup_by_extension(
|
55
|
+
mime_type = Mime::Type.lookup_by_extension(extension)
|
56
56
|
mime_type.to_s.match?(/^image/)
|
57
57
|
end
|
58
58
|
|
@@ -66,6 +66,12 @@ module RailsAdmin
|
|
66
66
|
}
|
67
67
|
end
|
68
68
|
|
69
|
+
def extension
|
70
|
+
URI.parse(resource_url).path.split('.').last
|
71
|
+
rescue URI::InvalidURIError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
69
75
|
# virtual class
|
70
76
|
def resource_url
|
71
77
|
raise 'not implemented'
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rails_admin/config/fields/
|
3
|
+
require 'rails_admin/config/fields/collection_association'
|
4
4
|
|
5
5
|
module RailsAdmin
|
6
6
|
module Config
|
7
7
|
module Fields
|
8
8
|
module Types
|
9
|
-
class HasAndBelongsToManyAssociation < RailsAdmin::Config::Fields::
|
9
|
+
class HasAndBelongsToManyAssociation < RailsAdmin::Config::Fields::CollectionAssociation
|
10
10
|
# Register field type for the type loader
|
11
11
|
RailsAdmin::Config::Fields::Types.register(self)
|
12
12
|
end
|
@@ -1,36 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rails_admin/config/fields/
|
3
|
+
require 'rails_admin/config/fields/collection_association'
|
4
4
|
|
5
5
|
module RailsAdmin
|
6
6
|
module Config
|
7
7
|
module Fields
|
8
8
|
module Types
|
9
|
-
class HasManyAssociation < RailsAdmin::Config::Fields::
|
9
|
+
class HasManyAssociation < RailsAdmin::Config::Fields::CollectionAssociation
|
10
10
|
# Register field type for the type loader
|
11
11
|
RailsAdmin::Config::Fields::Types.register(self)
|
12
|
-
|
13
|
-
register_instance_option :partial do
|
14
|
-
nested_form ? :form_nested_many : :form_filtering_multiselect
|
15
|
-
end
|
16
|
-
|
17
|
-
# orderable associated objects
|
18
|
-
register_instance_option :orderable do
|
19
|
-
false
|
20
|
-
end
|
21
|
-
|
22
|
-
def method_name
|
23
|
-
nested_form ? :"#{name}_attributes" : super
|
24
|
-
end
|
25
|
-
|
26
|
-
# Reader for validation errors of the bound object
|
27
|
-
def errors
|
28
|
-
bindings[:object].errors[name]
|
29
|
-
end
|
30
|
-
|
31
|
-
def associated_prepopulate_params
|
32
|
-
{associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
|
33
|
-
end
|
34
12
|
end
|
35
13
|
end
|
36
14
|
end
|
@@ -1,42 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rails_admin/config/fields/
|
3
|
+
require 'rails_admin/config/fields/singular_association'
|
4
4
|
|
5
5
|
module RailsAdmin
|
6
6
|
module Config
|
7
7
|
module Fields
|
8
8
|
module Types
|
9
|
-
class HasOneAssociation < RailsAdmin::Config::Fields::
|
9
|
+
class HasOneAssociation < RailsAdmin::Config::Fields::SingularAssociation
|
10
10
|
# Register field type for the type loader
|
11
11
|
RailsAdmin::Config::Fields::Types.register(self)
|
12
12
|
|
13
|
-
register_instance_option :
|
14
|
-
|
13
|
+
register_instance_option :allowed_methods do
|
14
|
+
nested_form ? [method_name] : [name]
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
# Accessor for field's formatted value
|
22
|
-
register_instance_option :formatted_value do
|
23
|
-
(o = value) && o.send(associated_model_config.object_label_method)
|
24
|
-
end
|
25
|
-
|
26
|
-
def selected_id
|
27
|
-
value.try(:id).try(:to_s)
|
17
|
+
def associated_prepopulate_params
|
18
|
+
{associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
|
28
19
|
end
|
29
20
|
|
30
|
-
def
|
31
|
-
|
32
|
-
end
|
21
|
+
def parse_input(params)
|
22
|
+
return super if nested_form
|
33
23
|
|
34
|
-
|
35
|
-
|
24
|
+
id = params.delete(method_name)
|
25
|
+
params[name] = associated_model_config.abstract_model.get(id) if id
|
36
26
|
end
|
37
27
|
|
38
|
-
def
|
39
|
-
|
28
|
+
def selected_id
|
29
|
+
format_key(value.try(:id)).try(:to_s)
|
40
30
|
end
|
41
31
|
end
|
42
32
|
end
|