madmin 1.2.1 → 1.2.5
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/controllers/madmin/application_controller.rb +22 -0
- data/app/controllers/madmin/resource_controller.rb +1 -1
- data/app/views/layouts/madmin/application.html.erb +1 -1
- data/app/views/madmin/application/_javascript.html.erb +1 -1
- data/app/views/madmin/application/index.html.erb +27 -24
- data/app/views/madmin/application/show.html.erb +1 -1
- data/app/views/madmin/fields/file/_form.html.erb +4 -0
- data/app/views/madmin/fields/file/_index.html.erb +1 -0
- data/app/views/madmin/fields/file/_show.html.erb +6 -0
- data/app/views/madmin/fields/integer/_index.html.erb +5 -1
- data/app/views/madmin/fields/nested_has_many/_fields.html.erb +2 -3
- data/app/views/madmin/fields/text/_index.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/field.rb +3 -2
- data/lib/madmin/fields/file.rb +9 -0
- data/lib/madmin/fields/nested_has_many.rb +1 -1
- data/lib/madmin/resource.rb +40 -23
- data/lib/madmin/resource_builder.rb +80 -0
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin.rb +2 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea857d0e707bca79172d1bcbecb72cfb939724279ab3f2c08546ff279fd38d03
|
|
4
|
+
data.tar.gz: c886c8ad0c5d0a11c81f1aecf45463e29205e9bf29dfe00fae4fc94466988ee0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65e7522be423638030455299a70bfdd21cc706e75a5b6624f7a41f869250517474b00dd514551914e86bb3b7e7dac31aa812826461a634649caba8456b73f5c8
|
|
7
|
+
data.tar.gz: faea74829b0c7e307960dcbe006986f51c064e147c00b17f1234bfc6b72246511c1d206d4891fd773f3f97ea05b96a87dbcdd3e9b709aac1141407a580529b26
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Madmin
|
|
2
|
+
class ApplicationController < Madmin::BaseController
|
|
3
|
+
before_action :authenticate_admin_user
|
|
4
|
+
|
|
5
|
+
def authenticate_admin_user
|
|
6
|
+
# TODO: Add your authentication logic here
|
|
7
|
+
|
|
8
|
+
# For example, we could redirect if the user isn't an admin
|
|
9
|
+
# redirect_to "/", alert: "Not authorized." unless user_signed_in? && current_user.admin?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Authenticate with Clearance
|
|
13
|
+
# include Clearance::Controller
|
|
14
|
+
# before_action :require_login
|
|
15
|
+
|
|
16
|
+
# Authenticate with Devise
|
|
17
|
+
# before_action :authenticate_user!
|
|
18
|
+
|
|
19
|
+
# Authenticate with Basic Auth
|
|
20
|
+
# http_basic_authenticate_with(name: Rails.application.credentials.admin_username, password: Rails.application.credentials.admin_password)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -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>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<%= stylesheet_link_tag "https://unpkg.com/tom-select/dist/css/tom-select.min.css", "data-turbo-track": "reload" %>
|
|
4
4
|
|
|
5
5
|
<script type="module">
|
|
6
|
-
import { Application, Controller } from 'https://cdn.skypack.dev/stimulus'
|
|
6
|
+
import { Application, Controller } from 'https://cdn.skypack.dev/@hotwired/stimulus'
|
|
7
7
|
const application = Application.start()
|
|
8
8
|
|
|
9
9
|
import { Dropdown } from "https://cdn.skypack.dev/tailwindcss-stimulus-components"
|
|
@@ -27,33 +27,36 @@
|
|
|
27
27
|
<%= link_to scope.to_s.humanize, resource.index_path(scope: scope), class: class_names("p-2 rounded", {"bg-gray-100" => params[:scope] == scope.to_s}) %>
|
|
28
28
|
<% end %>
|
|
29
29
|
</div>
|
|
30
|
-
|
|
31
|
-
<table class="min-w-full divide-y divide-gray-200">
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<% resource.attributes.values.each do |attribute| %>
|
|
35
|
-
<% next if attribute.field.nil? %>
|
|
36
|
-
<% next unless attribute.field.visible?(action_name) %>
|
|
37
|
-
|
|
38
|
-
<th class="py-2 px-4 text-left text-xs text-gray-500 font-medium uppercase whitespace-nowrap"><%= sortable attribute.name, attribute.name.to_s.titleize %></th>
|
|
39
|
-
<% end %>
|
|
40
|
-
<th class="py-2 px-4 text-left text-xs text-gray-500 font-medium uppercase">Actions</th>
|
|
41
|
-
</tr>
|
|
42
|
-
</thead>
|
|
43
|
-
|
|
44
|
-
<tbody class="text-sm divide-y">
|
|
45
|
-
<% @records.each do |record| %>
|
|
46
|
-
<tr>
|
|
30
|
+
<div class="min-w-full max-w-xl overflow-x-auto pb-4">
|
|
31
|
+
<table class="min-w-full divide-y divide-gray-200">
|
|
32
|
+
<thead>
|
|
33
|
+
<tr class="border-b border-gray-200">
|
|
47
34
|
<% resource.attributes.values.each do |attribute| %>
|
|
48
35
|
<% next if attribute.field.nil? %>
|
|
49
36
|
<% next unless attribute.field.visible?(action_name) %>
|
|
50
|
-
<td class="px-4 py-2"><%= render partial: attribute.field.to_partial_path("index"), locals: { field: attribute.field, record: record } %></td>
|
|
51
|
-
<% end %>
|
|
52
37
|
|
|
53
|
-
|
|
38
|
+
<th class="py-2 px-4 text-left text-xs text-gray-500 font-medium uppercase whitespace-nowrap"><%= sortable attribute.name, attribute.name.to_s.titleize %></th>
|
|
39
|
+
<% end %>
|
|
40
|
+
<th class="py-2 px-4 text-left text-xs text-gray-500 font-medium uppercase">Actions</th>
|
|
54
41
|
</tr>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
</thead>
|
|
43
|
+
|
|
44
|
+
<tbody class="text-sm divide-y">
|
|
45
|
+
<% @records.each do |record| %>
|
|
46
|
+
<tr>
|
|
47
|
+
<% resource.attributes.values.each do |attribute| %>
|
|
48
|
+
<% next if attribute.field.nil? %>
|
|
49
|
+
<% next unless attribute.field.visible?(action_name) %>
|
|
50
|
+
<td class="px-4 py-2"><%= render partial: attribute.field.to_partial_path("index"), locals: { field: attribute.field, record: record, resource: resource } %></td>
|
|
51
|
+
<% end %>
|
|
52
|
+
|
|
53
|
+
<td class="px-4 py-2 text-center">
|
|
54
|
+
<%= link_to "View", resource.show_path(record), class: "text-indigo-500" %>
|
|
55
|
+
<%= link_to "Edit", resource.edit_path(record), class: "text-indigo-500" %>
|
|
56
|
+
</td>
|
|
57
|
+
</tr>
|
|
58
|
+
<% end %>
|
|
59
|
+
</tbody>
|
|
60
|
+
</table>
|
|
61
|
+
</div>
|
|
59
62
|
<%== pagy_nav(@pagy) if @pagy.pages > 1 %>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
</div>
|
|
25
25
|
|
|
26
26
|
<div class="md:col-span-3">
|
|
27
|
-
<%= render partial: attribute.field.to_partial_path("show"), locals: { field: attribute.field, record: @record } %>
|
|
27
|
+
<%= render partial: attribute.field.to_partial_path("show"), locals: { field: attribute.field, record: @record, resource: resource } %>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
30
30
|
<% end %>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= field.value(record) %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<%= content_tag :div, class: "nested-fields
|
|
2
|
-
<% field.nested_attributes.each do |nested_attribute| %>
|
|
1
|
+
<%= content_tag :div, class: "nested-fields border border-gray-200 rounded-lg p-5", data: { new_record: f.object.new_record? } do %>
|
|
2
|
+
<% field.nested_attributes.each do |name, nested_attribute| %>
|
|
3
3
|
<% next if nested_attribute[:field].nil? %>
|
|
4
4
|
<% next unless nested_attribute[:field].visible?(action_name) %>
|
|
5
5
|
<% next unless nested_attribute[:field].visible?(:form) %>
|
|
@@ -14,5 +14,4 @@
|
|
|
14
14
|
<small><%= link_to "Remove", "#", data: { action: "click->nested-form#remove_association" } %></small>
|
|
15
15
|
|
|
16
16
|
<%= f.hidden_field :_destroy %>
|
|
17
|
-
|
|
18
17
|
<% end %>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<%= field.value(record) %>
|
|
1
|
+
<%= truncate field.value(record) %>
|
|
@@ -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/field.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
module Madmin
|
|
2
2
|
class Field
|
|
3
|
-
attr_reader :attribute_name, :model, :options
|
|
3
|
+
attr_reader :attribute_name, :model, :options, :resource
|
|
4
4
|
|
|
5
5
|
def self.field_type
|
|
6
6
|
to_s.split("::").last.underscore
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def initialize(attribute_name:, model:, **options)
|
|
9
|
+
def initialize(attribute_name:, model:, resource:, **options)
|
|
10
10
|
@attribute_name = attribute_name
|
|
11
11
|
@model = model
|
|
12
|
+
@resource = resource
|
|
12
13
|
@options = options
|
|
13
14
|
end
|
|
14
15
|
|
|
@@ -3,7 +3,7 @@ module Madmin
|
|
|
3
3
|
class NestedHasMany < Field
|
|
4
4
|
DEFAULT_ATTRIBUTES = %w[_destroy id].freeze
|
|
5
5
|
def nested_attributes
|
|
6
|
-
resource.attributes.reject { |
|
|
6
|
+
resource.attributes.reject { |name, attribute| skipped_fields.include?(name) }
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def resource
|
data/lib/madmin/resource.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Madmin
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def model
|
|
14
|
-
model_name.constantize
|
|
14
|
+
@model ||= model_name.constantize
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def model_find(id)
|
|
@@ -37,36 +37,51 @@ module Madmin
|
|
|
37
37
|
attributes[name] = OpenStruct.new(
|
|
38
38
|
name: name,
|
|
39
39
|
type: type,
|
|
40
|
-
field: field.new(**options.merge(attribute_name: name, model: model))
|
|
40
|
+
field: field.new(**options.merge(attribute_name: name, model: model, resource: self))
|
|
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
|
|
45
58
|
model_name.gsub("::", " / ")
|
|
46
59
|
end
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
# Support for isolated namespaces
|
|
62
|
+
# Finds parent module class to include in polymorphic urls
|
|
63
|
+
def route_namespace
|
|
64
|
+
return @route_namespace if instance_variable_defined?(:@route_namespace)
|
|
65
|
+
namespace = model.module_parents.detect do |n|
|
|
66
|
+
n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
|
|
67
|
+
end
|
|
68
|
+
@route_namespace = (namespace ? namespace.name.singularize.underscore.to_sym : nil)
|
|
69
|
+
end
|
|
50
70
|
|
|
51
|
-
|
|
71
|
+
def index_path(options = {})
|
|
72
|
+
url_helpers.polymorphic_path([:madmin, route_namespace, model], options)
|
|
52
73
|
end
|
|
53
74
|
|
|
54
75
|
def new_path
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
url_helpers.send(route_name)
|
|
76
|
+
url_helpers.polymorphic_path([:madmin, route_namespace, model], action: :new)
|
|
58
77
|
end
|
|
59
78
|
|
|
60
79
|
def show_path(record)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
url_helpers.send(route_name, record.to_param)
|
|
80
|
+
url_helpers.polymorphic_path([:madmin, route_namespace, record])
|
|
64
81
|
end
|
|
65
82
|
|
|
66
83
|
def edit_path(record)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
url_helpers.send(route_name, record.to_param)
|
|
84
|
+
url_helpers.polymorphic_path([:madmin, route_namespace, record], action: :edit)
|
|
70
85
|
end
|
|
71
86
|
|
|
72
87
|
def param_key
|
|
@@ -115,6 +130,7 @@ module Madmin
|
|
|
115
130
|
time: Fields::Time,
|
|
116
131
|
timestamp: Fields::Time,
|
|
117
132
|
password: Fields::Password,
|
|
133
|
+
file: Fields::File,
|
|
118
134
|
|
|
119
135
|
# Postgres specific types
|
|
120
136
|
bit: Fields::String,
|
|
@@ -154,15 +170,6 @@ module Madmin
|
|
|
154
170
|
rich_text: Fields::RichText,
|
|
155
171
|
nested_has_many: Fields::NestedHasMany
|
|
156
172
|
}.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
173
|
end
|
|
167
174
|
|
|
168
175
|
def infer_type(name)
|
|
@@ -187,6 +194,10 @@ module Madmin
|
|
|
187
194
|
# has_secure_password
|
|
188
195
|
elsif model.attribute_types.include?("#{name_string}_digest") || name_string.ends_with?("_confirmation")
|
|
189
196
|
:password
|
|
197
|
+
|
|
198
|
+
# ActiveRecord Store
|
|
199
|
+
elsif model_store_accessors.include?(name)
|
|
200
|
+
:string
|
|
190
201
|
end
|
|
191
202
|
end
|
|
192
203
|
|
|
@@ -205,6 +216,12 @@ module Madmin
|
|
|
205
216
|
def url_helpers
|
|
206
217
|
@url_helpers ||= Rails.application.routes.url_helpers
|
|
207
218
|
end
|
|
219
|
+
|
|
220
|
+
def model_store_accessors
|
|
221
|
+
store_accessors = model.stored_attributes.values
|
|
222
|
+
|
|
223
|
+
store_accessors.flatten
|
|
224
|
+
end
|
|
208
225
|
end
|
|
209
226
|
end
|
|
210
227
|
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
|
@@ -6,6 +6,7 @@ module Madmin
|
|
|
6
6
|
autoload :Field, "madmin/field"
|
|
7
7
|
autoload :GeneratorHelpers, "madmin/generator_helpers"
|
|
8
8
|
autoload :Resource, "madmin/resource"
|
|
9
|
+
autoload :ResourceBuilder, "madmin/resource_builder"
|
|
9
10
|
autoload :Search, "madmin/search"
|
|
10
11
|
|
|
11
12
|
module Fields
|
|
@@ -17,6 +18,7 @@ module Madmin
|
|
|
17
18
|
autoload :DateTime, "madmin/fields/date_time"
|
|
18
19
|
autoload :Decimal, "madmin/fields/decimal"
|
|
19
20
|
autoload :Enum, "madmin/fields/enum"
|
|
21
|
+
autoload :File, "madmin/fields/file"
|
|
20
22
|
autoload :Float, "madmin/fields/float"
|
|
21
23
|
autoload :HasMany, "madmin/fields/has_many"
|
|
22
24
|
autoload :HasOne, "madmin/fields/has_one"
|
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.5
|
|
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-25 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rails
|
|
@@ -59,6 +59,7 @@ files:
|
|
|
59
59
|
- app/assets/config/manifest.js
|
|
60
60
|
- app/assets/stylesheets/actiontext.scss
|
|
61
61
|
- app/assets/stylesheets/application.css
|
|
62
|
+
- app/controllers/madmin/application_controller.rb
|
|
62
63
|
- app/controllers/madmin/base_controller.rb
|
|
63
64
|
- app/controllers/madmin/dashboard_controller.rb
|
|
64
65
|
- app/controllers/madmin/resource_controller.rb
|
|
@@ -98,6 +99,9 @@ files:
|
|
|
98
99
|
- app/views/madmin/fields/enum/_form.html.erb
|
|
99
100
|
- app/views/madmin/fields/enum/_index.html.erb
|
|
100
101
|
- app/views/madmin/fields/enum/_show.html.erb
|
|
102
|
+
- app/views/madmin/fields/file/_form.html.erb
|
|
103
|
+
- app/views/madmin/fields/file/_index.html.erb
|
|
104
|
+
- app/views/madmin/fields/file/_show.html.erb
|
|
101
105
|
- app/views/madmin/fields/float/_form.html.erb
|
|
102
106
|
- app/views/madmin/fields/float/_index.html.erb
|
|
103
107
|
- app/views/madmin/fields/float/_show.html.erb
|
|
@@ -167,6 +171,7 @@ files:
|
|
|
167
171
|
- lib/madmin/fields/date_time.rb
|
|
168
172
|
- lib/madmin/fields/decimal.rb
|
|
169
173
|
- lib/madmin/fields/enum.rb
|
|
174
|
+
- lib/madmin/fields/file.rb
|
|
170
175
|
- lib/madmin/fields/float.rb
|
|
171
176
|
- lib/madmin/fields/has_many.rb
|
|
172
177
|
- lib/madmin/fields/has_one.rb
|
|
@@ -182,6 +187,7 @@ files:
|
|
|
182
187
|
- lib/madmin/generator_helpers.rb
|
|
183
188
|
- lib/madmin/namespace.rb
|
|
184
189
|
- lib/madmin/resource.rb
|
|
190
|
+
- lib/madmin/resource_builder.rb
|
|
185
191
|
- lib/madmin/search.rb
|
|
186
192
|
- lib/madmin/version.rb
|
|
187
193
|
- lib/madmin/view_generator.rb
|