madmin 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/views/layouts/madmin/application.html.erb +1 -1
- data/lib/generators/madmin/resource/resource_generator.rb +8 -58
- data/lib/generators/madmin/resource/templates/resource.rb.tt +1 -1
- data/lib/madmin/engine.rb +3 -3
- data/lib/madmin/resource.rb +23 -9
- data/lib/madmin/resource_builder.rb +80 -0
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '05151328dcf6fdd8c23755a1b1f3f14b9dcceadc8215e6f102e133d915e95be6'
|
4
|
+
data.tar.gz: 305bf51253018fa0c871d0314e9ecd69339c510160cdacf1439c2fd361a95a97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 625d77d1c5ee5bd30462c2609a8b53b7c5d321fb97e0951a95b852eca019189d468c596fcda77e170ed996bd25707feea787a3668faf318a542a65f03d75e488
|
7
|
+
data.tar.gz: b594b3c324289e44dbdeb3f0acc70a532b391f8c46faa4854ea5654e9dfe648c88062e24c29433bb476165134a0d79fdbbca526000bbf6c148e9c2c28777f0ed
|
@@ -19,7 +19,7 @@
|
|
19
19
|
<div id="sidebar" class="md:w-64 p-4 flex-shrink-0 border-r">
|
20
20
|
<%= render "navigation" -%>
|
21
21
|
</div>
|
22
|
-
<main class="flex-grow p-4" role="main">
|
22
|
+
<main class="flex-grow p-4 overflow-x-scroll" role="main">
|
23
23
|
<%#= render "flashes" -%>
|
24
24
|
<%= yield %>
|
25
25
|
</main>
|
@@ -28,69 +28,19 @@ module Madmin
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
def
|
32
|
-
model
|
33
|
-
# Hide these special associations
|
34
|
-
name.starts_with?("rich_text") ||
|
35
|
-
name.ends_with?("_attachment") ||
|
36
|
-
name.ends_with?("_attachments") ||
|
37
|
-
name.ends_with?("_blob") ||
|
38
|
-
name.ends_with?("_blobs")
|
39
|
-
}.keys
|
31
|
+
def model
|
32
|
+
@model ||= class_name.constantize
|
40
33
|
end
|
41
34
|
|
42
|
-
def
|
43
|
-
|
35
|
+
def resource_builder
|
36
|
+
@resource_builder ||= ResourceBuilder.new(model)
|
44
37
|
end
|
45
38
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
# has_secure_password columns
|
50
|
-
password_attributes = model.attribute_types.keys.select { |k| k.ends_with?("_digest") }.map { |k| k.delete_suffix("_digest") }
|
51
|
-
virtual += password_attributes.map { |attr| [attr, "#{attr}_confirmation"] }.flatten
|
52
|
-
|
53
|
-
# Add virtual attributes for ActionText and ActiveStorage
|
54
|
-
model.reflections.each do |name, association|
|
55
|
-
if name.starts_with?("rich_text")
|
56
|
-
virtual << name.split("rich_text_").last
|
57
|
-
elsif name.ends_with?("_attachment")
|
58
|
-
virtual << name.split("_attachment").first
|
59
|
-
elsif name.ends_with?("_attachments")
|
60
|
-
virtual << name.split("_attachments").first
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
virtual
|
39
|
+
def model_attributes
|
40
|
+
resource_builder.attributes
|
65
41
|
end
|
66
42
|
|
67
|
-
|
68
|
-
redundant = []
|
69
|
-
|
70
|
-
# has_secure_password columns
|
71
|
-
redundant += model.attribute_types.keys.select { |k| k.ends_with?("_digest") }
|
72
|
-
|
73
|
-
model.reflections.each do |name, association|
|
74
|
-
if association.has_one?
|
75
|
-
next
|
76
|
-
elsif association.collection?
|
77
|
-
next
|
78
|
-
elsif association.polymorphic?
|
79
|
-
redundant << "#{name}_id"
|
80
|
-
redundant << "#{name}_type"
|
81
|
-
elsif name.starts_with?("rich_text")
|
82
|
-
redundant << name
|
83
|
-
else # belongs to
|
84
|
-
redundant << "#{name}_id"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
redundant
|
89
|
-
end
|
90
|
-
|
91
|
-
def model
|
92
|
-
@model ||= class_name.constantize
|
93
|
-
end
|
43
|
+
delegate :associations, :virtual_attributes, :store_accessors, to: :resource_builder
|
94
44
|
|
95
45
|
def formatted_options_for_attribute(name)
|
96
46
|
options = options_for_attribute(name)
|
@@ -114,7 +64,7 @@ module Madmin
|
|
114
64
|
{form: false}
|
115
65
|
|
116
66
|
# Attributes without a database column
|
117
|
-
elsif !model.column_names.include?(name)
|
67
|
+
elsif !model.column_names.include?(name) && !store_accessors.map(&:to_s).include?(name)
|
118
68
|
{index: false}
|
119
69
|
end
|
120
70
|
end
|
data/lib/madmin/engine.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Madmin
|
2
2
|
class Engine < ::Rails::Engine
|
3
|
-
|
4
|
-
app.config.
|
5
|
-
app.config.
|
3
|
+
config.before_configuration do |app|
|
4
|
+
app.config.autoload_paths << File.expand_path("app/madmin/resources", Rails.root)
|
5
|
+
app.config.autoload_paths << File.expand_path("app/madmin/fields", Rails.root)
|
6
6
|
end
|
7
7
|
|
8
8
|
config.to_prepare do
|
data/lib/madmin/resource.rb
CHANGED
@@ -39,6 +39,19 @@ module Madmin
|
|
39
39
|
type: type,
|
40
40
|
field: field.new(**options.merge(attribute_name: name, model: model))
|
41
41
|
)
|
42
|
+
rescue => e
|
43
|
+
builder = ResourceBuilder.new(model)
|
44
|
+
raise ArgumentError, <<~MESSAGE
|
45
|
+
Madmin couldn't find attribute or association '#{name}' on #{model} model.
|
46
|
+
|
47
|
+
We searched these attributes and associations:
|
48
|
+
#{(builder.attributes + builder.associations).join(", ")}
|
49
|
+
|
50
|
+
This attribute is defined in a Madmin resource at:
|
51
|
+
#{e.backtrace.find { |l| l =~ /_resource.rb/ }}
|
52
|
+
|
53
|
+
Either add the missing attribute or assocation, or remove this line from your Madmin resource.
|
54
|
+
MESSAGE
|
42
55
|
end
|
43
56
|
|
44
57
|
def friendly_name
|
@@ -154,15 +167,6 @@ module Madmin
|
|
154
167
|
rich_text: Fields::RichText,
|
155
168
|
nested_has_many: Fields::NestedHasMany
|
156
169
|
}.fetch(type)
|
157
|
-
rescue
|
158
|
-
raise ArgumentError, <<~MESSAGE
|
159
|
-
Couldn't find attribute or association '#{name}' with type '#{type}' on #{model} model
|
160
|
-
|
161
|
-
To fix this, either:
|
162
|
-
|
163
|
-
1. Remove 'attribute #{name}' from app/madmin/resources/#{model.to_s.underscore}_resource.rb
|
164
|
-
2. Or add the missing attribute or association to the #{model} model
|
165
|
-
MESSAGE
|
166
170
|
end
|
167
171
|
|
168
172
|
def infer_type(name)
|
@@ -187,6 +191,10 @@ module Madmin
|
|
187
191
|
# has_secure_password
|
188
192
|
elsif model.attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
|
189
193
|
:password
|
194
|
+
|
195
|
+
# ActiveRecord Store
|
196
|
+
elsif model_store_accessors.include?(name)
|
197
|
+
:string
|
190
198
|
end
|
191
199
|
end
|
192
200
|
|
@@ -205,6 +213,12 @@ module Madmin
|
|
205
213
|
def url_helpers
|
206
214
|
@url_helpers ||= Rails.application.routes.url_helpers
|
207
215
|
end
|
216
|
+
|
217
|
+
def model_store_accessors
|
218
|
+
store_accessors = model.stored_attributes.values
|
219
|
+
|
220
|
+
store_accessors.flatten
|
221
|
+
end
|
208
222
|
end
|
209
223
|
end
|
210
224
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Madmin
|
2
|
+
class ResourceBuilder
|
3
|
+
attr_reader :model
|
4
|
+
|
5
|
+
def initialize(model)
|
6
|
+
@model = model
|
7
|
+
end
|
8
|
+
|
9
|
+
def associations
|
10
|
+
model.reflections.reject { |name, association|
|
11
|
+
# Hide these special associations
|
12
|
+
name.starts_with?("rich_text") ||
|
13
|
+
name.ends_with?("_attachment") ||
|
14
|
+
name.ends_with?("_attachments") ||
|
15
|
+
name.ends_with?("_blob") ||
|
16
|
+
name.ends_with?("_blobs")
|
17
|
+
}.keys
|
18
|
+
end
|
19
|
+
|
20
|
+
def attributes
|
21
|
+
model.attribute_names + virtual_attributes - redundant_attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
def store_accessors
|
25
|
+
model.stored_attributes.values.flatten
|
26
|
+
end
|
27
|
+
|
28
|
+
def virtual_attributes
|
29
|
+
virtual = []
|
30
|
+
|
31
|
+
# has_secure_password columns
|
32
|
+
password_attributes = model.attribute_types.keys.select { |k| k.ends_with?("_digest") }.map { |k| k.delete_suffix("_digest") }
|
33
|
+
virtual += password_attributes.map { |attr| [attr, "#{attr}_confirmation"] }.flatten
|
34
|
+
|
35
|
+
# ActiveRecord Store columns
|
36
|
+
virtual += store_accessors.map(&:to_s)
|
37
|
+
|
38
|
+
# Add virtual attributes for ActionText and ActiveStorage
|
39
|
+
model.reflections.each do |name, association|
|
40
|
+
if name.starts_with?("rich_text")
|
41
|
+
virtual << name.split("rich_text_").last
|
42
|
+
elsif name.ends_with?("_attachment")
|
43
|
+
virtual << name.split("_attachment").first
|
44
|
+
elsif name.ends_with?("_attachments")
|
45
|
+
virtual << name.split("_attachments").first
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
virtual
|
50
|
+
end
|
51
|
+
|
52
|
+
def redundant_attributes
|
53
|
+
redundant = []
|
54
|
+
|
55
|
+
# has_secure_password columns
|
56
|
+
redundant += model.attribute_types.keys.select { |k| k.ends_with?("_digest") }
|
57
|
+
|
58
|
+
# ActiveRecord Store columns
|
59
|
+
store_columns = model.stored_attributes.keys
|
60
|
+
redundant += store_columns.map(&:to_s)
|
61
|
+
|
62
|
+
model.reflections.each do |name, association|
|
63
|
+
if association.has_one?
|
64
|
+
next
|
65
|
+
elsif association.collection?
|
66
|
+
next
|
67
|
+
elsif association.polymorphic?
|
68
|
+
redundant << "#{name}_id"
|
69
|
+
redundant << "#{name}_type"
|
70
|
+
elsif name.starts_with?("rich_text")
|
71
|
+
redundant << name
|
72
|
+
else # belongs to
|
73
|
+
redundant << "#{name}_id"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
redundant
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/madmin/version.rb
CHANGED
data/lib/madmin.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: madmin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Oliver
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-09-
|
12
|
+
date: 2021-09-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -182,6 +182,7 @@ files:
|
|
182
182
|
- lib/madmin/generator_helpers.rb
|
183
183
|
- lib/madmin/namespace.rb
|
184
184
|
- lib/madmin/resource.rb
|
185
|
+
- lib/madmin/resource_builder.rb
|
185
186
|
- lib/madmin/search.rb
|
186
187
|
- lib/madmin/version.rb
|
187
188
|
- lib/madmin/view_generator.rb
|