administrate 0.18.0 → 0.20.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/app/assets/javascripts/administrate/components/select.js +3 -0
- data/app/assets/stylesheets/administrate/components/_field-unit.scss +7 -0
- data/app/controllers/administrate/application_controller.rb +7 -4
- data/app/controllers/concerns/administrate/punditize.rb +43 -21
- data/app/views/administrate/application/_collection.html.erb +2 -3
- data/app/views/administrate/application/_form.html.erb +19 -4
- data/app/views/administrate/application/_index_header.html.erb +1 -1
- data/app/views/administrate/application/_navigation.html.erb +1 -1
- data/app/views/administrate/application/_pagination.html.erb +1 -1
- data/app/views/administrate/application/edit.html.erb +1 -1
- data/app/views/administrate/application/new.html.erb +1 -1
- data/app/views/administrate/application/show.html.erb +19 -11
- data/app/views/fields/has_many/_show.html.erb +2 -1
- data/app/views/fields/has_one/_form.html.erb +14 -4
- data/app/views/fields/has_one/_show.html.erb +18 -12
- data/app/views/fields/select/_form.html.erb +5 -18
- data/app/views/layouts/administrate/application.html.erb +1 -1
- data/config/locales/administrate.ja.yml +5 -5
- data/docs/authorization.md +18 -8
- data/docs/customizing_controller_actions.md +14 -0
- data/docs/customizing_dashboards.md +77 -14
- data/docs/customizing_page_views.md +1 -1
- data/docs/getting_started.md +1 -1
- data/docs/guides/customising_search.md +1 -1
- data/lib/administrate/base_dashboard.rb +26 -4
- data/lib/administrate/field/associative.rb +11 -1
- data/lib/administrate/field/belongs_to.rb +5 -2
- data/lib/administrate/field/deferred.rb +1 -1
- data/lib/administrate/field/has_many.rb +20 -6
- data/lib/administrate/field/number.rb +2 -8
- data/lib/administrate/field/polymorphic.rb +2 -1
- data/lib/administrate/field/select.rb +19 -9
- data/lib/administrate/not_authorized_error.rb +3 -1
- data/lib/administrate/order.rb +49 -23
- data/lib/administrate/page/collection.rb +1 -0
- data/lib/administrate/page/form.rb +9 -8
- data/lib/administrate/page/show.rb +10 -2
- data/lib/administrate/resource_resolver.rb +2 -1
- data/lib/administrate/search.rb +1 -1
- data/lib/administrate/version.rb +1 -1
- data/lib/administrate/view_generator.rb +6 -1
- data/lib/administrate.rb +9 -4
- data/lib/generators/administrate/dashboard/dashboard_generator.rb +6 -1
- data/lib/generators/administrate/dashboard/templates/controller.rb.erb +2 -2
- data/lib/generators/administrate/install/install_generator.rb +6 -1
- data/lib/generators/administrate/routes/routes_generator.rb +11 -2
- data/lib/generators/administrate/test_record.rb +21 -0
- metadata +37 -17
data/docs/getting_started.md
CHANGED
@@ -3,7 +3,7 @@ title: Getting Started
|
|
3
3
|
---
|
4
4
|
|
5
5
|
Administrate is released as a Ruby gem, and can be installed on Rails
|
6
|
-
applications version
|
6
|
+
applications version 6.0 or greater. We support Ruby 3.0 and up.
|
7
7
|
|
8
8
|
First, add the following to your Gemfile:
|
9
9
|
|
@@ -135,7 +135,7 @@ records.
|
|
135
135
|
|
136
136
|
## A working example
|
137
137
|
|
138
|
-
The [Administrate demo app](/admin)
|
138
|
+
The [Administrate demo app](https://administrate-demo.herokuapp.com/admin)
|
139
139
|
includes an example of custom search in the "Log Entries" dashboard.
|
140
140
|
In this app, each `LogEntry` instance has a polymorphic `belongs_to`
|
141
141
|
association to a `:logeable`. Logeables are other models for which logs can be
|
@@ -51,6 +51,12 @@ module Administrate
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def form_attributes(action = nil)
|
54
|
+
action =
|
55
|
+
case action
|
56
|
+
when "update" then "edit"
|
57
|
+
when "create" then "new"
|
58
|
+
else action
|
59
|
+
end
|
54
60
|
specific_form_attributes_for(action) || self.class::FORM_ATTRIBUTES
|
55
61
|
end
|
56
62
|
|
@@ -62,11 +68,18 @@ module Administrate
|
|
62
68
|
self.class.const_get(cname) if self.class.const_defined?(cname)
|
63
69
|
end
|
64
70
|
|
65
|
-
def permitted_attributes
|
66
|
-
form_attributes
|
71
|
+
def permitted_attributes(action = nil)
|
72
|
+
attributes = form_attributes action
|
73
|
+
|
74
|
+
if attributes.is_a? Hash
|
75
|
+
attributes = attributes.values.flatten
|
76
|
+
end
|
77
|
+
|
78
|
+
attributes.map do |attr|
|
67
79
|
attribute_types[attr].permitted_attribute(
|
68
80
|
attr,
|
69
81
|
resource_class: self.class.model,
|
82
|
+
action: action,
|
70
83
|
)
|
71
84
|
end.uniq
|
72
85
|
end
|
@@ -76,7 +89,11 @@ module Administrate
|
|
76
89
|
end
|
77
90
|
|
78
91
|
def collection_attributes
|
79
|
-
self.class::COLLECTION_ATTRIBUTES
|
92
|
+
if self.class::COLLECTION_ATTRIBUTES.is_a?(Hash)
|
93
|
+
self.class::COLLECTION_ATTRIBUTES.values.flatten
|
94
|
+
else
|
95
|
+
self.class::COLLECTION_ATTRIBUTES
|
96
|
+
end
|
80
97
|
end
|
81
98
|
|
82
99
|
def search_attributes
|
@@ -100,7 +117,12 @@ module Administrate
|
|
100
117
|
end
|
101
118
|
|
102
119
|
def item_associations
|
103
|
-
|
120
|
+
attributes = if show_page_attributes.is_a?(Hash)
|
121
|
+
show_page_attributes.values.flatten
|
122
|
+
else
|
123
|
+
show_page_attributes
|
124
|
+
end
|
125
|
+
attribute_associated attributes
|
104
126
|
end
|
105
127
|
|
106
128
|
private
|
@@ -7,6 +7,10 @@ module Administrate
|
|
7
7
|
reflection(resource_class, attr).foreign_key
|
8
8
|
end
|
9
9
|
|
10
|
+
def self.association_primary_key_for(resource_class, attr)
|
11
|
+
reflection(resource_class, attr).association_primary_key
|
12
|
+
end
|
13
|
+
|
10
14
|
def self.associated_class(resource_class, attr)
|
11
15
|
reflection(resource_class, attr).klass
|
12
16
|
end
|
@@ -49,10 +53,16 @@ module Administrate
|
|
49
53
|
end
|
50
54
|
|
51
55
|
def primary_key
|
56
|
+
# Deprecated, renamed `association_primary_key`
|
57
|
+
Administrate.warn_of_deprecated_method(self.class, :primary_key)
|
58
|
+
association_primary_key
|
59
|
+
end
|
60
|
+
|
61
|
+
def association_primary_key
|
52
62
|
if option_given?(:primary_key)
|
53
63
|
deprecated_option(:primary_key)
|
54
64
|
else
|
55
|
-
|
65
|
+
self.class.association_primary_key_for(resource.class, attribute)
|
56
66
|
end
|
57
67
|
end
|
58
68
|
|
@@ -23,12 +23,15 @@ module Administrate
|
|
23
23
|
|
24
24
|
def associated_resource_options
|
25
25
|
candidate_resources.map do |resource|
|
26
|
-
[
|
26
|
+
[
|
27
|
+
display_candidate_resource(resource),
|
28
|
+
resource.send(association_primary_key),
|
29
|
+
]
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
30
33
|
def selected_option
|
31
|
-
data
|
34
|
+
data&.send(association_primary_key)
|
32
35
|
end
|
33
36
|
|
34
37
|
def include_blank_option
|
@@ -22,7 +22,11 @@ module Administrate
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def associated_collection(order = self.order)
|
25
|
-
Administrate::Page::Collection.new(
|
25
|
+
Administrate::Page::Collection.new(
|
26
|
+
associated_dashboard,
|
27
|
+
order: order,
|
28
|
+
collection_attributes: options[:collection_attributes],
|
29
|
+
)
|
26
30
|
end
|
27
31
|
|
28
32
|
def attribute_key
|
@@ -30,21 +34,28 @@ module Administrate
|
|
30
34
|
end
|
31
35
|
|
32
36
|
def associated_resource_options
|
33
|
-
candidate_resources.map do |
|
34
|
-
[
|
37
|
+
candidate_resources.map do |associated_resource|
|
38
|
+
[
|
39
|
+
display_candidate_resource(associated_resource),
|
40
|
+
associated_resource.send(association_primary_key),
|
41
|
+
]
|
35
42
|
end
|
36
43
|
end
|
37
44
|
|
38
45
|
def selected_options
|
39
46
|
return if data.empty?
|
40
47
|
|
41
|
-
data.map { |object| object.send(
|
48
|
+
data.map { |object| object.send(association_primary_key) }
|
42
49
|
end
|
43
50
|
|
44
51
|
def limit
|
45
52
|
options.fetch(:limit, DEFAULT_LIMIT)
|
46
53
|
end
|
47
54
|
|
55
|
+
def paginate?
|
56
|
+
limit.respond_to?(:positive?) ? limit.positive? : limit.present?
|
57
|
+
end
|
58
|
+
|
48
59
|
def permitted_attribute
|
49
60
|
self.class.permitted_attribute(
|
50
61
|
attribute,
|
@@ -53,12 +64,15 @@ module Administrate
|
|
53
64
|
end
|
54
65
|
|
55
66
|
def resources(page = 1, order = self.order)
|
56
|
-
resources = order.apply(data)
|
67
|
+
resources = order.apply(data)
|
68
|
+
if paginate?
|
69
|
+
resources = resources.page(page).per(limit)
|
70
|
+
end
|
57
71
|
includes.any? ? resources.includes(*includes) : resources
|
58
72
|
end
|
59
73
|
|
60
74
|
def more_than_limit?
|
61
|
-
data.count(:all) > limit
|
75
|
+
paginate? && data.count(:all) > limit
|
62
76
|
end
|
63
77
|
|
64
78
|
def data
|
@@ -38,14 +38,8 @@ module Administrate
|
|
38
38
|
formatter = options[:format][:formatter]
|
39
39
|
formatter_options = options[:format][:formatter_options].to_h
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
ActiveSupport::NumberHelper.number_to_delimited(
|
44
|
-
result, **formatter_options
|
45
|
-
)
|
46
|
-
else
|
47
|
-
result
|
48
|
-
end
|
41
|
+
ActiveSupport::NumberHelper.
|
42
|
+
try(formatter, result, **formatter_options) || result
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
@@ -8,22 +8,32 @@ module Administrate
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def selectable_options
|
11
|
-
|
11
|
+
values =
|
12
|
+
if options.key?(:collection)
|
13
|
+
options.fetch(:collection)
|
14
|
+
elsif active_record_enum?
|
15
|
+
active_record_enum_values
|
16
|
+
else
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
if values.respond_to? :call
|
21
|
+
values = values.arity.positive? ? values.call(self) : values.call
|
22
|
+
end
|
23
|
+
|
24
|
+
values
|
12
25
|
end
|
13
26
|
|
14
27
|
def include_blank_option
|
15
28
|
options.fetch(:include_blank, false)
|
16
29
|
end
|
17
30
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
values = options.fetch(:collection, [])
|
22
|
-
if values.respond_to? :call
|
23
|
-
return values.arity.positive? ? values.call(self) : values.call
|
24
|
-
end
|
31
|
+
def active_record_enum?
|
32
|
+
resource.class.defined_enums.key?(attribute.to_s)
|
33
|
+
end
|
25
34
|
|
26
|
-
|
35
|
+
def active_record_enum_values
|
36
|
+
resource.class.defined_enums[attribute.to_s].map(&:first)
|
27
37
|
end
|
28
38
|
end
|
29
39
|
end
|
@@ -5,8 +5,10 @@ module Administrate
|
|
5
5
|
@resource = resource
|
6
6
|
|
7
7
|
case resource
|
8
|
-
when
|
8
|
+
when String, Symbol
|
9
9
|
super("Not allowed to perform #{action.inspect} on #{resource.inspect}")
|
10
|
+
when Module
|
11
|
+
super("Not allowed to perform #{action.inspect} on #{resource.name}")
|
10
12
|
else
|
11
13
|
super(
|
12
14
|
"Not allowed to perform #{action.inspect} on the given " +
|
data/lib/administrate/order.rb
CHANGED
@@ -10,9 +10,9 @@ module Administrate
|
|
10
10
|
return order_by_association(relation) unless
|
11
11
|
reflect_association(relation).nil?
|
12
12
|
|
13
|
-
order =
|
13
|
+
order = relation.arel_table[attribute].public_send(direction)
|
14
14
|
|
15
|
-
return relation.reorder(
|
15
|
+
return relation.reorder(order) if
|
16
16
|
column_exist?(relation, attribute)
|
17
17
|
|
18
18
|
relation
|
@@ -52,36 +52,57 @@ module Administrate
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def order_by_association(relation)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
case relation_type(relation)
|
56
|
+
when :has_many
|
57
|
+
order_by_count(relation)
|
58
|
+
when :belongs_to
|
59
|
+
order_by_belongs_to(relation)
|
60
|
+
when :has_one
|
61
|
+
order_by_has_one(relation)
|
62
|
+
else
|
63
|
+
relation
|
64
|
+
end
|
60
65
|
end
|
61
66
|
|
62
67
|
def order_by_count(relation)
|
63
68
|
klass = reflect_association(relation).klass
|
64
|
-
query =
|
69
|
+
query = klass.arel_table[klass.primary_key].count.public_send(direction)
|
65
70
|
relation.
|
66
71
|
left_joins(attribute.to_sym).
|
67
72
|
group(:id).
|
68
|
-
reorder(
|
73
|
+
reorder(query)
|
69
74
|
end
|
70
75
|
|
71
|
-
def
|
72
|
-
|
76
|
+
def order_by_belongs_to(relation)
|
77
|
+
if ordering_by_association_column?(relation)
|
78
|
+
order_by_attribute(relation)
|
79
|
+
else
|
80
|
+
order_by_id(relation)
|
81
|
+
end
|
73
82
|
end
|
74
83
|
|
75
|
-
def
|
84
|
+
def order_by_has_one(relation)
|
76
85
|
if ordering_by_association_column?(relation)
|
77
|
-
relation
|
78
|
-
attribute.to_sym,
|
79
|
-
).reorder(Arel.sql(order_by_attribute_query))
|
86
|
+
order_by_attribute(relation)
|
80
87
|
else
|
81
|
-
|
88
|
+
order_by_association_id(relation)
|
82
89
|
end
|
83
90
|
end
|
84
91
|
|
92
|
+
def order_by_attribute(relation)
|
93
|
+
relation.joins(
|
94
|
+
attribute.to_sym,
|
95
|
+
).reorder(order_by_attribute_query)
|
96
|
+
end
|
97
|
+
|
98
|
+
def order_by_id(relation)
|
99
|
+
relation.reorder(order_by_id_query(relation))
|
100
|
+
end
|
101
|
+
|
102
|
+
def order_by_association_id(relation)
|
103
|
+
relation.reorder(order_by_association_id_query)
|
104
|
+
end
|
105
|
+
|
85
106
|
def ordering_by_association_column?(relation)
|
86
107
|
association_attribute &&
|
87
108
|
column_exist?(
|
@@ -94,19 +115,20 @@ module Administrate
|
|
94
115
|
end
|
95
116
|
|
96
117
|
def order_by_id_query(relation)
|
97
|
-
|
118
|
+
relation.arel_table[foreign_key(relation)].public_send(direction)
|
98
119
|
end
|
99
120
|
|
100
|
-
def
|
101
|
-
|
121
|
+
def order_by_association_id_query
|
122
|
+
Arel::Table.new(association_table_name)[:id].public_send(direction)
|
102
123
|
end
|
103
124
|
|
104
|
-
def
|
105
|
-
|
125
|
+
def order_by_attribute_query
|
126
|
+
table = Arel::Table.new(association_table_name)
|
127
|
+
table[association_attribute].public_send(direction)
|
106
128
|
end
|
107
129
|
|
108
|
-
def
|
109
|
-
reflect_association(relation).macro
|
130
|
+
def relation_type(relation)
|
131
|
+
reflect_association(relation).macro
|
110
132
|
end
|
111
133
|
|
112
134
|
def reflect_association(relation)
|
@@ -116,5 +138,9 @@ module Administrate
|
|
116
138
|
def foreign_key(relation)
|
117
139
|
reflect_association(relation).foreign_key
|
118
140
|
end
|
141
|
+
|
142
|
+
def association_table_name
|
143
|
+
attribute.tableize
|
144
|
+
end
|
119
145
|
end
|
120
146
|
end
|
@@ -11,15 +11,16 @@ module Administrate
|
|
11
11
|
attr_reader :resource
|
12
12
|
|
13
13
|
def attributes(action = nil)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
14
|
+
attributes = dashboard.form_attributes(action)
|
15
|
+
|
16
|
+
if attributes.is_a? Array
|
17
|
+
attributes = { "" => attributes }
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
20
|
+
attributes.transform_values do |attrs|
|
21
|
+
attrs.map do |attribute|
|
22
|
+
attribute_field(dashboard, resource, attribute, :form)
|
23
|
+
end
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -15,8 +15,16 @@ module Administrate
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def attributes
|
18
|
-
dashboard.show_page_attributes
|
19
|
-
|
18
|
+
attributes = dashboard.show_page_attributes
|
19
|
+
|
20
|
+
if attributes.is_a? Array
|
21
|
+
attributes = { "" => attributes }
|
22
|
+
end
|
23
|
+
|
24
|
+
attributes.transform_values do |attrs|
|
25
|
+
attrs.map do |attr_name|
|
26
|
+
attribute_field(dashboard, resource, attr_name, :show)
|
27
|
+
end
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
data/lib/administrate/search.rb
CHANGED
data/lib/administrate/version.rb
CHANGED
@@ -5,7 +5,12 @@ require "administrate/namespace"
|
|
5
5
|
module Administrate
|
6
6
|
class ViewGenerator < Rails::Generators::Base
|
7
7
|
include Administrate::GeneratorHelpers
|
8
|
-
class_option
|
8
|
+
class_option(
|
9
|
+
:namespace,
|
10
|
+
type: :string,
|
11
|
+
desc: "Namespace where the admin dashboards live",
|
12
|
+
default: "admin",
|
13
|
+
)
|
9
14
|
|
10
15
|
def self.template_source_path
|
11
16
|
File.expand_path(
|
data/lib/administrate.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require "administrate/engine"
|
2
|
+
require "administrate/version"
|
2
3
|
|
3
4
|
module Administrate
|
4
5
|
def self.warn_of_missing_resource_class
|
5
|
-
|
6
|
+
deprecator.warn(
|
6
7
|
"Calling Field::Base.permitted_attribute without the option " +
|
7
8
|
":resource_class is deprecated. If you are seeing this " +
|
8
9
|
"message, you are probably using a custom field type that" +
|
@@ -12,7 +13,7 @@ module Administrate
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.warn_of_deprecated_option(name)
|
15
|
-
|
16
|
+
deprecator.warn(
|
16
17
|
"The option :#{name} is deprecated. " +
|
17
18
|
"Administrate should detect it automatically. " +
|
18
19
|
"Please file an issue at " +
|
@@ -22,7 +23,7 @@ module Administrate
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def self.warn_of_deprecated_method(klass, method)
|
25
|
-
|
26
|
+
deprecator.warn(
|
26
27
|
"The method #{klass}##{method} is deprecated. " +
|
27
28
|
"If you are seeing this message you are probably " +
|
28
29
|
"using a dashboard that depends explicitly on it. " +
|
@@ -32,10 +33,14 @@ module Administrate
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def self.warn_of_deprecated_authorization_method(method)
|
35
|
-
|
36
|
+
deprecator.warn(
|
36
37
|
"The method `#{method}` is deprecated. " +
|
37
38
|
"Please use `accessible_action?` instead, " +
|
38
39
|
"or see the documentation for other options.",
|
39
40
|
)
|
40
41
|
end
|
42
|
+
|
43
|
+
def self.deprecator
|
44
|
+
@deprecator ||= ActiveSupport::Deprecation.new(VERSION, "Administrate")
|
45
|
+
end
|
41
46
|
end
|
@@ -27,7 +27,12 @@ module Administrate
|
|
27
27
|
COLLECTION_ATTRIBUTE_LIMIT = 4
|
28
28
|
READ_ONLY_ATTRIBUTES = %w[id created_at updated_at]
|
29
29
|
|
30
|
-
class_option
|
30
|
+
class_option(
|
31
|
+
:namespace,
|
32
|
+
type: :string,
|
33
|
+
desc: "Namespace where the admin dashboards live",
|
34
|
+
default: "admin",
|
35
|
+
)
|
31
36
|
|
32
37
|
source_root File.expand_path("../templates", __FILE__)
|
33
38
|
|
@@ -36,11 +36,11 @@ module <%= namespace.to_s.camelize %>
|
|
36
36
|
#
|
37
37
|
# def resource_params
|
38
38
|
# params.require(resource_class.model_name.param_key).
|
39
|
-
# permit(dashboard.permitted_attributes).
|
39
|
+
# permit(dashboard.permitted_attributes(action_name)).
|
40
40
|
# transform_values { |value| value == "" ? nil : value }
|
41
41
|
# end
|
42
42
|
|
43
|
-
# See https://administrate-
|
43
|
+
# See https://administrate-demo.herokuapp.com/customizing_controller_actions
|
44
44
|
# for more information
|
45
45
|
end
|
46
46
|
end
|
@@ -14,7 +14,12 @@ module Administrate
|
|
14
14
|
include Administrate::GeneratorHelpers
|
15
15
|
source_root File.expand_path("../templates", __FILE__)
|
16
16
|
|
17
|
-
class_option
|
17
|
+
class_option(
|
18
|
+
:namespace,
|
19
|
+
type: :string,
|
20
|
+
desc: "Namespace where the admin dashboards will live",
|
21
|
+
default: "admin",
|
22
|
+
)
|
18
23
|
|
19
24
|
def run_routes_generator
|
20
25
|
if dashboard_resources.none?
|
@@ -7,13 +7,19 @@ end
|
|
7
7
|
require "rails/generators/base"
|
8
8
|
require "administrate/generator_helpers"
|
9
9
|
require "administrate/namespace"
|
10
|
+
require "generators/administrate/test_record"
|
10
11
|
|
11
12
|
module Administrate
|
12
13
|
module Generators
|
13
14
|
class RoutesGenerator < Rails::Generators::Base
|
14
15
|
include Administrate::GeneratorHelpers
|
15
16
|
source_root File.expand_path("../templates", __FILE__)
|
16
|
-
class_option
|
17
|
+
class_option(
|
18
|
+
:namespace,
|
19
|
+
type: :string,
|
20
|
+
desc: "Namespace where the admin dashboards live",
|
21
|
+
default: "admin",
|
22
|
+
)
|
17
23
|
|
18
24
|
def insert_dashboard_routes
|
19
25
|
if valid_dashboard_models.any?
|
@@ -55,7 +61,10 @@ module Administrate
|
|
55
61
|
end
|
56
62
|
|
57
63
|
def database_models
|
58
|
-
ActiveRecord::Base.descendants.
|
64
|
+
ActiveRecord::Base.descendants.
|
65
|
+
reject(&:abstract_class?).
|
66
|
+
reject { |k| k < Administrate::Generators::TestRecord }.
|
67
|
+
sort_by(&:to_s)
|
59
68
|
end
|
60
69
|
|
61
70
|
def invalid_dashboard_models
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Administrate
|
2
|
+
module Generators
|
3
|
+
# This class serves only to work around a strange behaviour in Rails 7
|
4
|
+
# with Ruby 3.
|
5
|
+
#
|
6
|
+
# After running the spec for DashboardGenerator, the fake models that
|
7
|
+
# it generates (eg: Foo, Shipment) linger around despite being removed
|
8
|
+
# explicitly. This causes RouteGenerator to take them into
|
9
|
+
# account and generate routes for them, which its spec doesn't expect,
|
10
|
+
# causing a spec failure.
|
11
|
+
#
|
12
|
+
# To avoid this, the spec for DashboardGenerator defines its fake models
|
13
|
+
# as children of TestRecord. Then RoutesGenerator explicitly filters
|
14
|
+
# child classes of TestRecord when figuring out what models exist.
|
15
|
+
#
|
16
|
+
# Discussion at https://github.com/thoughtbot/administrate/pull/2324
|
17
|
+
class TestRecord < ApplicationRecord
|
18
|
+
self.abstract_class = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|