rails_admin 3.1.1 → 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 +4 -4
- data/Gemfile +23 -17
- data/README.md +6 -4
- 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 +16 -1
- data/app/helpers/rails_admin/application_helper.rb +4 -0
- data/app/helpers/rails_admin/form_builder.rb +6 -5
- data/app/helpers/rails_admin/main_helper.rb +1 -1
- data/app/views/layouts/rails_admin/_head.html.erb +10 -7
- 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/app/views/rails_admin/main/index.html.erb +2 -2
- data/config/initializers/active_record_extensions.rb +0 -23
- data/lib/generators/rails_admin/importmap_formatter.rb +3 -2
- 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 +28 -11
- data/lib/rails_admin/adapters/active_record/object_extension.rb +0 -18
- data/lib/rails_admin/adapters/active_record.rb +56 -5
- data/lib/rails_admin/adapters/mongoid/association.rb +4 -4
- data/lib/rails_admin/adapters/mongoid/bson.rb +1 -0
- data/lib/rails_admin/adapters/mongoid/object_extension.rb +0 -5
- data/lib/rails_admin/adapters/mongoid.rb +13 -3
- data/lib/rails_admin/config/actions/export.rb +2 -1
- data/lib/rails_admin/config/actions/index.rb +7 -5
- data/lib/rails_admin/config/actions/show.rb +1 -1
- data/lib/rails_admin/config/configurable.rb +1 -1
- data/lib/rails_admin/config/fields/association.rb +41 -2
- data/lib/rails_admin/config/fields/base.rb +5 -5
- data/lib/rails_admin/config/fields/collection_association.rb +90 -0
- data/lib/rails_admin/config/fields/factories/active_storage.rb +2 -2
- data/lib/rails_admin/config/fields/factories/carrierwave.rb +1 -1
- data/lib/rails_admin/config/fields/factories/dragonfly.rb +1 -1
- data/lib/rails_admin/config/fields/factories/paperclip.rb +1 -1
- data/lib/rails_admin/config/fields/factories/shrine.rb +1 -1
- 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/model.rb +3 -1
- data/lib/rails_admin/config.rb +9 -5
- data/lib/rails_admin/engine.rb +5 -0
- data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +1 -1
- data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -1
- 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/csv_converter.rb +0 -1
- data/lib/rails_admin/support/datetime.rb +1 -0
- data/lib/rails_admin/support/serialization_schema.rb +72 -0
- data/lib/rails_admin/version.rb +1 -1
- data/lib/rails_admin.rb +1 -0
- 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
- data/src/rails_admin/ui.js +7 -1
- metadata +41 -18
- 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
|
@@ -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".to_sym : 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
|
|
@@ -23,19 +23,16 @@ module RailsAdmin
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
register_instance_option :image? do
|
|
26
|
-
|
|
27
|
-
mime_type = Mime::Type.lookup_by_extension(value.filename.extension_without_delimiter)
|
|
28
|
-
mime_type.to_s.match?(/^image/)
|
|
29
|
-
end
|
|
26
|
+
value && (value.representable? || value.content_type.match?(/^image/))
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
def resource_url(thumb = false)
|
|
33
30
|
return nil unless value
|
|
34
31
|
|
|
35
|
-
if thumb && value.
|
|
36
|
-
|
|
32
|
+
if thumb && value.representable?
|
|
33
|
+
representation = value.representation(thumb_method)
|
|
37
34
|
Rails.application.routes.url_helpers.rails_blob_representation_path(
|
|
38
|
-
|
|
35
|
+
representation.blob.signed_id, representation.variation.key, representation.blob.filename, only_path: true
|
|
39
36
|
)
|
|
40
37
|
else
|
|
41
38
|
Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
|
|
@@ -48,7 +45,7 @@ module RailsAdmin
|
|
|
48
45
|
end
|
|
49
46
|
|
|
50
47
|
register_instance_option :keep_method do
|
|
51
|
-
method_name if ::ActiveStorage.replace_on_assign_to_many
|
|
48
|
+
method_name if ::ActiveStorage.gem_version >= Gem::Version.new('7.1') || ::ActiveStorage.replace_on_assign_to_many
|
|
52
49
|
end
|
|
53
50
|
|
|
54
51
|
register_instance_option :delete_method do
|
|
@@ -70,6 +67,14 @@ module RailsAdmin
|
|
|
70
67
|
direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},
|
|
71
68
|
)
|
|
72
69
|
end
|
|
70
|
+
|
|
71
|
+
register_instance_option :searchable do
|
|
72
|
+
false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
register_instance_option :sortable do
|
|
76
|
+
false
|
|
77
|
+
end
|
|
73
78
|
end
|
|
74
79
|
end
|
|
75
80
|
end
|
|
@@ -47,13 +47,19 @@ module RailsAdmin
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
register_instance_option :image? do
|
|
50
|
-
mime_type = Mime::Type.lookup_by_extension(
|
|
50
|
+
mime_type = Mime::Type.lookup_by_extension(extension)
|
|
51
51
|
mime_type.to_s.match?(/^image/)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def resource_url(_thumb = false)
|
|
55
55
|
raise 'not implemented'
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
def extension
|
|
59
|
+
URI.parse(resource_url).path.split('.').last
|
|
60
|
+
rescue URI::InvalidURIError
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
def initialize(*args)
|
|
@@ -51,26 +51,29 @@ module RailsAdmin
|
|
|
51
51
|
false
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
def
|
|
55
|
-
|
|
54
|
+
def associated_model_config
|
|
55
|
+
@associated_model_config ||= association.klass.collect { |type| RailsAdmin.config(type) }.reject(&:excluded?)
|
|
56
|
+
end
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
[
|
|
58
|
+
def collection(_scope = nil)
|
|
59
|
+
if value
|
|
60
|
+
[[formatted_value, selected_id]]
|
|
61
|
+
else
|
|
62
|
+
[[]]
|
|
60
63
|
end
|
|
61
64
|
end
|
|
62
65
|
|
|
63
|
-
def
|
|
64
|
-
|
|
66
|
+
def type_column
|
|
67
|
+
association.foreign_type.to_s
|
|
65
68
|
end
|
|
66
69
|
|
|
67
|
-
def
|
|
70
|
+
def type_collection
|
|
68
71
|
associated_model_config.collect do |config|
|
|
69
72
|
[config.label, config.abstract_model.model.name]
|
|
70
73
|
end
|
|
71
74
|
end
|
|
72
75
|
|
|
73
|
-
def
|
|
76
|
+
def type_urls
|
|
74
77
|
types = associated_model_config.collect do |config|
|
|
75
78
|
[config.abstract_model.model.name, config.abstract_model.to_param]
|
|
76
79
|
end
|
|
@@ -82,6 +85,26 @@ module RailsAdmin
|
|
|
82
85
|
bindings[:object].send(association.name)
|
|
83
86
|
end
|
|
84
87
|
|
|
88
|
+
def widget_options_for_types
|
|
89
|
+
type_collection.inject({}) do |options, model|
|
|
90
|
+
options.merge(
|
|
91
|
+
model.second.downcase.gsub('::', '-') => {
|
|
92
|
+
xhr: true,
|
|
93
|
+
remote_source: bindings[:view].index_path(model.second.underscore, source_object_id: bindings[:object].id, source_abstract_model: abstract_model.to_param, current_action: bindings[:view].current_action, compact: true),
|
|
94
|
+
float_left: false,
|
|
95
|
+
},
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def widget_options
|
|
101
|
+
widget_options_for_types[selected_type.try(:downcase)] || {float_left: false}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def selected_type
|
|
105
|
+
bindings[:object].send(type_column)
|
|
106
|
+
end
|
|
107
|
+
|
|
85
108
|
def parse_input(params)
|
|
86
109
|
if (type_value = params[association.foreign_type.to_sym]).present?
|
|
87
110
|
config = associated_model_config.find { |c| type_value == c.abstract_model.model.name }
|
|
@@ -48,7 +48,9 @@ module RailsAdmin
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def excluded?
|
|
51
|
-
@excluded
|
|
51
|
+
return @excluded if defined?(@excluded)
|
|
52
|
+
|
|
53
|
+
@excluded = !RailsAdmin::AbstractModel.all.collect(&:model_name).include?(abstract_model.try(:model_name))
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
def object_label
|
data/lib/rails_admin/config.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rails_admin/config/lazy_model'
|
|
4
4
|
require 'rails_admin/config/sections/list'
|
|
5
|
+
require 'rails_admin/support/composite_keys_serializer'
|
|
5
6
|
require 'active_support/core_ext/module/attribute_accessors'
|
|
6
7
|
|
|
7
8
|
module RailsAdmin
|
|
@@ -84,6 +85,9 @@ module RailsAdmin
|
|
|
84
85
|
# Set where RailsAdmin fetches JS/CSS from, defaults to :sprockets
|
|
85
86
|
attr_writer :asset_source
|
|
86
87
|
|
|
88
|
+
# For customization of composite keys representation
|
|
89
|
+
attr_accessor :composite_keys_serializer
|
|
90
|
+
|
|
87
91
|
# Setup authentication to be run as a before filter
|
|
88
92
|
# This is run inside the controller instance so you can setup any authentication you need to
|
|
89
93
|
#
|
|
@@ -329,6 +333,7 @@ module RailsAdmin
|
|
|
329
333
|
@navigation_static_links = {}
|
|
330
334
|
@navigation_static_label = nil
|
|
331
335
|
@asset_source = nil
|
|
336
|
+
@composite_keys_serializer = RailsAdmin::Support::CompositeKeysSerializer
|
|
332
337
|
@parent_controller = '::ActionController::Base'
|
|
333
338
|
@forgery_protection_settings = {with: :exception}
|
|
334
339
|
RailsAdmin::Config::Actions.reset
|
|
@@ -364,23 +369,22 @@ module RailsAdmin
|
|
|
364
369
|
|
|
365
370
|
private
|
|
366
371
|
|
|
367
|
-
def lchomp(base, arg)
|
|
368
|
-
base.to_s.reverse.chomp(arg.to_s.reverse).reverse
|
|
369
|
-
end
|
|
370
|
-
|
|
371
372
|
def viable_models
|
|
372
373
|
included_models.collect(&:to_s).presence || begin
|
|
373
374
|
@@system_models ||= # memoization for tests
|
|
374
375
|
([Rails.application] + Rails::Engine.subclasses.collect(&:instance)).flat_map do |app|
|
|
375
376
|
(app.paths['app/models'].to_a + app.config.eager_load_paths).collect do |load_path|
|
|
376
377
|
Dir.glob(app.root.join(load_path)).collect do |load_dir|
|
|
378
|
+
path_prefix = "#{app.root.join(load_dir)}/"
|
|
377
379
|
Dir.glob("#{load_dir}/**/*.rb").collect do |filename|
|
|
378
380
|
# app/models/module/class.rb => module/class.rb => module/class => Module::Class
|
|
379
|
-
|
|
381
|
+
filename.delete_prefix(path_prefix).chomp('.rb').camelize
|
|
380
382
|
end
|
|
381
383
|
end
|
|
382
384
|
end
|
|
383
385
|
end.flatten.reject { |m| m.starts_with?('Concerns::') } # rubocop:disable Style/MultilineBlockChain
|
|
386
|
+
|
|
387
|
+
@@system_models + @registry.keys.collect(&:to_s)
|
|
384
388
|
end
|
|
385
389
|
end
|
|
386
390
|
|
data/lib/rails_admin/engine.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'kaminari'
|
|
|
4
4
|
require 'nested_form'
|
|
5
5
|
require 'rails'
|
|
6
6
|
require 'rails_admin'
|
|
7
|
+
require 'rails_admin/extensions/url_for_extension'
|
|
7
8
|
require 'rails_admin/version'
|
|
8
9
|
require 'turbo-rails'
|
|
9
10
|
|
|
@@ -15,6 +16,10 @@ module RailsAdmin
|
|
|
15
16
|
|
|
16
17
|
config.action_dispatch.rescue_responses['RailsAdmin::ActionNotAllowed'] = :forbidden
|
|
17
18
|
|
|
19
|
+
initializer 'RailsAdmin load UrlForExtension' do
|
|
20
|
+
RailsAdmin::Engine.routes.singleton_class.prepend(RailsAdmin::Extensions::UrlForExtension)
|
|
21
|
+
end
|
|
22
|
+
|
|
18
23
|
initializer 'RailsAdmin reload config in development' do |app|
|
|
19
24
|
config.initializer_path = app.root.join('config/initializers/rails_admin.rb')
|
|
20
25
|
|
|
@@ -146,7 +146,7 @@ module RailsAdmin
|
|
|
146
146
|
versions = object.nil? ? versions_for_model(model) : object.public_send(model.model.versions_association_name)
|
|
147
147
|
versions = versions.where('event LIKE ?', "%#{query}%") if query.present?
|
|
148
148
|
versions = versions.order(sort)
|
|
149
|
-
versions =
|
|
149
|
+
versions = versions.send(Kaminari.config.page_method_name, current_page).per(per_page) unless all
|
|
150
150
|
paginated_proxies = Kaminari.paginate_array([], total_count: versions.try(:total_count) || versions.count)
|
|
151
151
|
paginated_proxies = paginated_proxies.send(
|
|
152
152
|
paginated_proxies.respond_to?(Kaminari.config.page_method_name) ? Kaminari.config.page_method_name : :page,
|
|
@@ -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
|
-
|
|
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,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAdmin
|
|
4
|
+
module Extensions
|
|
5
|
+
module UrlForExtension
|
|
6
|
+
def url_for(options, *args)
|
|
7
|
+
case options[:id]
|
|
8
|
+
when Array
|
|
9
|
+
options[:id] = RailsAdmin.config.composite_keys_serializer.serialize(options[:id])
|
|
10
|
+
end
|
|
11
|
+
super options, *args
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsAdmin
|
|
4
|
+
module Support
|
|
5
|
+
module CompositeKeysSerializer
|
|
6
|
+
def self.serialize(keys)
|
|
7
|
+
keys.map { |key| key&.to_s&.gsub('_', '__') }.join('_')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.deserialize(string)
|
|
11
|
+
string.split('_').map { |key| key&.gsub('__', '_') }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -21,6 +21,7 @@ module RailsAdmin
|
|
|
21
21
|
'%-I' => 'h', # Hour of the day, 12-hour clock (1..12)
|
|
22
22
|
'%k' => 'H', # Hour of the day, 24-hour clock (0..23)
|
|
23
23
|
'%l' => 'h', # Hour of the day, 12-hour clock (1..12)
|
|
24
|
+
'%-l' => 'h', # Hour of the day, 12-hour clock (1..12)
|
|
24
25
|
'%M' => 'i', # Minute of the hour (00..59)
|
|
25
26
|
'%-M' => 'i', # Minute of the hour (00..59)
|
|
26
27
|
'%m' => 'm', # Month of the year (01..12)
|