madmin 1.0.1 → 1.2.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/README.md +29 -1
- data/app/controllers/madmin/base_controller.rb +0 -5
- data/app/controllers/madmin/resource_controller.rb +23 -2
- data/app/helpers/madmin/application_helper.rb +4 -0
- data/app/helpers/madmin/nav_helper.rb +30 -0
- data/app/helpers/madmin/sort_helper.rb +32 -0
- data/app/views/layouts/madmin/application.html.erb +5 -5
- data/app/views/madmin/application/_form.html.erb +6 -8
- data/app/views/madmin/application/_javascript.html.erb +73 -7
- data/app/views/madmin/application/_navigation.html.erb +31 -5
- data/app/views/madmin/application/edit.html.erb +5 -1
- data/app/views/madmin/application/index.html.erb +34 -22
- data/app/views/madmin/application/new.html.erb +5 -1
- data/app/views/madmin/application/show.html.erb +24 -17
- data/app/views/madmin/fields/attachment/_form.html.erb +3 -1
- data/app/views/madmin/fields/attachment/_show.html.erb +7 -1
- data/app/views/madmin/fields/attachments/_form.html.erb +3 -1
- data/app/views/madmin/fields/attachments/_show.html.erb +7 -3
- data/app/views/madmin/fields/belongs_to/_form.html.erb +4 -2
- data/app/views/madmin/fields/belongs_to/_show.html.erb +1 -1
- data/app/views/madmin/fields/boolean/_form.html.erb +3 -1
- data/app/views/madmin/fields/date/_form.html.erb +3 -1
- data/app/views/madmin/fields/date_time/_form.html.erb +3 -1
- data/app/views/madmin/fields/decimal/_form.html.erb +3 -1
- data/app/views/madmin/fields/enum/_form.html.erb +4 -2
- data/app/views/madmin/fields/float/_form.html.erb +3 -1
- data/app/views/madmin/fields/has_many/_form.html.erb +4 -2
- data/app/views/madmin/fields/has_many/_show.html.erb +1 -1
- data/app/views/madmin/fields/has_one/_form.html.erb +3 -2
- data/app/views/madmin/fields/integer/_form.html.erb +3 -1
- data/app/views/madmin/fields/json/_form.html.erb +3 -1
- data/app/views/madmin/fields/nested_has_many/_fields.html.erb +18 -0
- data/app/views/madmin/fields/nested_has_many/_form.html.erb +32 -0
- data/app/views/madmin/fields/nested_has_many/_index.html.erb +1 -0
- data/app/views/madmin/fields/nested_has_many/_show.html.erb +5 -0
- data/app/views/madmin/fields/password/_form.html.erb +4 -0
- data/app/views/madmin/fields/password/_index.html.erb +1 -0
- data/app/views/madmin/fields/password/_show.html.erb +1 -0
- data/app/views/madmin/fields/polymorphic/_form.html.erb +3 -1
- data/app/views/madmin/fields/polymorphic/_show.html.erb +1 -1
- data/app/views/madmin/fields/rich_text/_form.html.erb +3 -1
- data/app/views/madmin/fields/string/_form.html.erb +3 -1
- data/app/views/madmin/fields/text/_form.html.erb +3 -1
- data/app/views/madmin/fields/time/_form.html.erb +3 -1
- data/app/views/madmin/shared/_label.html.erb +4 -0
- data/lib/generators/madmin/field/field_generator.rb +31 -0
- data/lib/generators/madmin/field/templates/_form.html.erb +2 -0
- data/lib/generators/madmin/field/templates/_index.html.erb +1 -0
- data/lib/generators/madmin/field/templates/_show.html.erb +1 -0
- data/lib/generators/madmin/field/templates/field.rb.tt +26 -0
- data/lib/generators/madmin/install/install_generator.rb +6 -1
- data/lib/generators/madmin/install/templates/routes.rb.tt +3 -0
- data/lib/generators/madmin/resource/resource_generator.rb +15 -4
- data/lib/generators/madmin/resource/templates/controller.rb.tt +6 -0
- data/lib/generators/madmin/resource/templates/resource.rb.tt +14 -0
- data/lib/generators/madmin/views/javascript_generator.rb +15 -0
- data/lib/generators/madmin/views/views_generator.rb +6 -5
- data/lib/madmin/engine.rb +1 -1
- data/lib/madmin/field.rb +4 -0
- data/lib/madmin/fields/belongs_to.rb +9 -5
- data/lib/madmin/fields/has_many.rb +10 -5
- data/lib/madmin/fields/nested_has_many.rb +40 -0
- data/lib/madmin/fields/password.rb +6 -0
- data/lib/madmin/fields/string.rb +3 -0
- data/lib/madmin/fields/text.rb +3 -0
- data/lib/madmin/generator_helpers.rb +22 -4
- data/lib/madmin/resource.rb +53 -19
- data/lib/madmin/search.rb +60 -0
- data/lib/madmin/version.rb +1 -1
- data/lib/madmin.rb +30 -14
- metadata +25 -5
@@ -1,3 +1,7 @@
|
|
1
|
-
<h1
|
1
|
+
<h1 class="text-xl mb-4">
|
2
|
+
<%= link_to resource.friendly_name.pluralize, resource.index_path, class: "text-indigo-500" %>
|
3
|
+
/
|
4
|
+
<strong>New <%= resource.friendly_name %></strong>
|
5
|
+
</h1>
|
2
6
|
|
3
7
|
<%= render partial: "form", locals: { record: @record, resource: resource } %>
|
@@ -1,24 +1,31 @@
|
|
1
|
-
<div class="flex justify-between">
|
2
|
-
<h1
|
1
|
+
<div class="md:flex items-center justify-between mb-4">
|
2
|
+
<h1 class="text-xl">
|
3
|
+
<%= link_to resource.friendly_name.pluralize, resource.index_path, class: "text-indigo-500" %>
|
4
|
+
/
|
5
|
+
<%= link_to resource.display_name(@record), resource.show_path(@record), class: "text-indigo-500 font-bold" %>
|
6
|
+
</h1>
|
3
7
|
|
4
|
-
<div class="flex px-4">
|
5
|
-
|
6
|
-
|
8
|
+
<div class="flex items-center px-4">
|
9
|
+
<div class="mr-2">
|
10
|
+
<%= link_to "Edit", resource.edit_path(@record), class: "block bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 px-4 border border-gray-400 rounded shadow" %>
|
11
|
+
</div>
|
12
|
+
<%= button_to "Delete", resource.show_path(@record), method: :delete, data: { confirm: "Are you sure?" }, class: "bg-white hover:bg-gray-100 text-red-500 font-semibold py-2 px-4 border border-red-500 rounded shadow pointer-cursor" %>
|
7
13
|
</div>
|
8
14
|
</div>
|
9
15
|
|
10
|
-
|
11
|
-
<%
|
12
|
-
|
13
|
-
|
16
|
+
<div class="divide-y">
|
17
|
+
<% resource.attributes.values.each do |attribute| %>
|
18
|
+
<% next if attribute.field.nil? %>
|
19
|
+
<% next unless attribute.field.visible?(action_name) %>
|
14
20
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
<div class="px-4 py-3 md:grid md:grid-cols-4 md:gap-4 md:px-6">
|
22
|
+
<div class="text-sm font-medium text-gray-500">
|
23
|
+
<%= attribute.field.attribute_name.to_s.titleize %>
|
24
|
+
</div>
|
19
25
|
|
20
|
-
|
21
|
-
|
26
|
+
<div class="md:col-span-3">
|
27
|
+
<%= render partial: attribute.field.to_partial_path("show"), locals: { field: attribute.field, record: @record } %>
|
28
|
+
</div>
|
22
29
|
</div>
|
23
|
-
|
24
|
-
|
30
|
+
<% end %>
|
31
|
+
</div>
|
@@ -1,3 +1,9 @@
|
|
1
1
|
<% if (attachment = field.value(record)) && attachment.attached? %>
|
2
|
-
|
2
|
+
<% if attachment.variable? %>
|
3
|
+
<%= link_to attachment, target: :_blank do %>
|
4
|
+
<%= image_tag attachment, class: "max-h-32" %>
|
5
|
+
<% end %>
|
6
|
+
<% else %>
|
7
|
+
<%= link_to attachment.filename, attachment, target: :_blank, class: "text-indigo-500 underline" %>
|
8
|
+
<% end %>
|
3
9
|
<% end %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.file_field field.attribute_name, multiple: true %>
|
@@ -1,7 +1,11 @@
|
|
1
1
|
<% if (attachments = field.value(record)) && attachments.attached? %>
|
2
2
|
<% attachments.each do |attachment| %>
|
3
|
-
|
4
|
-
<%= link_to attachment
|
5
|
-
|
3
|
+
<% if attachment.variable? %>
|
4
|
+
<%= link_to attachment, target: :_blank do %>
|
5
|
+
<%= image_tag attachment, class: "max-h-32" %>
|
6
|
+
<% end %>
|
7
|
+
<% else %>
|
8
|
+
<%= link_to attachment.filename, attachment, target: :_blank, class: "text-indigo-500 underline" %>
|
9
|
+
<% end %>
|
6
10
|
<% end %>
|
7
11
|
<% end %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
<%=
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
4
|
+
<%= form.select field.to_param, field.options_for_select(record), { prompt: true }, { class: "form-select", data: { controller: "select", select_url_value: field.index_path } } %>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<% if (object = field.value(record)) %>
|
2
|
-
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
|
2
|
+
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
|
3
3
|
<% end %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.check_box field.attribute_name, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.text_field field.attribute_name, { class: "form-select", data: { controller: "flatpickr" } } %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.text_field field.attribute_name, data: { controller: "flatpickr", flatpickr_enable_time: true } %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.number_field field.attribute_name, step: :any, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
<%=
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
4
|
+
<%= form.select field.attribute_name, field.options_for_select(record), { prompt: true }, { class: "form-select", data: { controller: "select" } } %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.number_field field.attribute_name, step: :any, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
<%=
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
4
|
+
<%= form.select "#{field.attribute_name.to_s.singularize}_ids", field.options_for_select(record), { prompt: true }, { multiple: true, class: "form-select", data: { controller: "select", select_url_value: field.index_path } } %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% field.value(record).each do |object| %>
|
2
2
|
<div>
|
3
|
-
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
|
3
|
+
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
|
4
4
|
</div>
|
5
5
|
<% end %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.number_field field.attribute_name, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.text_area field.attribute_name, class: "form-input" %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= content_tag :div, class: "nested-fields bg-gray-100 rounded-t-xl p-5", data: { new_record: f.object.new_record? } do %>
|
2
|
+
<% field.nested_attributes.each do |nested_attribute| %>
|
3
|
+
<% next if nested_attribute[:field].nil? %>
|
4
|
+
<% next unless nested_attribute[:field].visible?(action_name) %>
|
5
|
+
<% next unless nested_attribute[:field].visible?(:form) %>
|
6
|
+
|
7
|
+
<% nested_field = nested_attribute[:field] %>
|
8
|
+
|
9
|
+
<div class="mb-4 flex">
|
10
|
+
<%= render partial: nested_field.to_partial_path("form"), locals: { field: nested_field, record: f.object, form: f, resource: field.resource } %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<small><%= link_to "Remove", "#", data: { action: "click->nested-form#remove_association" } %></small>
|
15
|
+
|
16
|
+
<%= f.hidden_field :_destroy %>
|
17
|
+
|
18
|
+
<% end %>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<div class="block md:inline-block w-32 flex-shrink-0">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<div class="container space-y-8" data-controller="nested-form">
|
6
|
+
<template data-target="nested-form.template">
|
7
|
+
|
8
|
+
<%= form.fields_for field.attribute_name, field.to_model.new, child_index: 'NEW_RECORD' do |nested_form| %>
|
9
|
+
<%= render(
|
10
|
+
partial: field.to_partial_path('fields'),
|
11
|
+
locals: {
|
12
|
+
f: nested_form,
|
13
|
+
field: field
|
14
|
+
}
|
15
|
+
) %>
|
16
|
+
<% end %>
|
17
|
+
</template>
|
18
|
+
|
19
|
+
<%= form.fields_for field.attribute_name do |nested_form| %>
|
20
|
+
<%= render(
|
21
|
+
partial: field.to_partial_path('fields'),
|
22
|
+
locals: {
|
23
|
+
f: nested_form,
|
24
|
+
field: field
|
25
|
+
}
|
26
|
+
) %>
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<%= content_tag :div, class: '', data: { target:"nested-form.links" } do %>
|
30
|
+
<%= link_to "+ Add new", "#", data: { action: "click->nested-form#add_association" } %>
|
31
|
+
<% end %>
|
32
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= pluralize field.value(record).count, field.attribute_name.to_s %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= field.value(record) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= field.value(record) %>
|
@@ -1,5 +1,7 @@
|
|
1
1
|
<%= form.fields_for field.attribute_name do |pf| %>
|
2
|
-
|
2
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
3
|
+
<%= render "madmin/shared/label", form: pf, field: field %>
|
4
|
+
</div>
|
3
5
|
<%= pf.select :value, field.options_for_select(record).map(&:to_global_id), { selected: field.value(record)&.to_global_id, prompt: true }, { class: "form-select", data: { controller: "slimselect" } } %>
|
4
6
|
<%= pf.hidden_field :type, value: "polymorphic" %>
|
5
7
|
<% end %>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<% if (object = field.value(record)) %>
|
2
|
-
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
|
2
|
+
<%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object), class: "text-indigo-500 underline" %>
|
3
3
|
<% end %>
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<div class="flex-1">
|
3
5
|
<%= form.rich_text_area field.attribute_name, class: "form-input block" %>
|
4
6
|
</div>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.text_field field.attribute_name, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.text_area field.attribute_name, class: "form-input" %>
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
1
|
+
<div class="block md:inline-block md:w-32 flex-shrink-0 text-gray-700">
|
2
|
+
<%= render "madmin/shared/label", form: form, field: field %>
|
3
|
+
</div>
|
2
4
|
<%= form.time_select field.attribute_name, {}, { class: "form-select" } %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Madmin
|
2
|
+
module Generators
|
3
|
+
class FieldGenerator < Rails::Generators::NamedBase
|
4
|
+
include Madmin::GeneratorHelpers
|
5
|
+
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def eager_load
|
9
|
+
Rails.application.eager_load!
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_field
|
13
|
+
template "field.rb", "app/madmin/fields/#{file_path}_field.rb"
|
14
|
+
copy_resource_template "_form"
|
15
|
+
copy_resource_template "_index"
|
16
|
+
copy_resource_template "_show"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def copy_resource_template(template_name)
|
22
|
+
template_file = "#{template_name}.html.erb"
|
23
|
+
|
24
|
+
copy_file(
|
25
|
+
template_file,
|
26
|
+
"app/views/madmin/fields/#{file_path}_field/#{template_file}"
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= field.value(record) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= field.value(record) %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class <%= class_name %>Field < Madmin::Field
|
2
|
+
# def value(record)
|
3
|
+
# record.public_send(attribute_name)
|
4
|
+
# end
|
5
|
+
|
6
|
+
# def to_partial_path(name)
|
7
|
+
# unless %w[index show form].include? name
|
8
|
+
# raise ArgumentError, "`partial` must be 'index', 'show', or 'form'"
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# "/madmin/fields/#{self.class.field_type}/#{name}"
|
12
|
+
# end
|
13
|
+
|
14
|
+
# def to_param
|
15
|
+
# attribute_name
|
16
|
+
# end
|
17
|
+
|
18
|
+
# # Used for checking visibility of attribute on an view
|
19
|
+
# def visible?(action, default: true)
|
20
|
+
# options.fetch(action.to_sym, default)
|
21
|
+
# end
|
22
|
+
|
23
|
+
# def required?
|
24
|
+
# model.validators_on(attribute_name).any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
|
25
|
+
# end
|
26
|
+
end
|
@@ -16,8 +16,13 @@ module Madmin
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def generate_routes
|
19
|
+
if rails6_1_and_up?
|
20
|
+
route "draw :madmin", file: ROUTES_FILE[:default]
|
21
|
+
template("routes.rb.tt", "config/routes/madmin.rb")
|
22
|
+
end
|
23
|
+
|
19
24
|
if route_namespace_exists?
|
20
|
-
route "root to: \"dashboard#show\"", indentation: 4, sentinel: /namespace :madmin do\s*\n/m
|
25
|
+
route "root to: \"dashboard#show\"", indentation: separated_routes_file? ? 2 : 4, sentinel: /namespace :madmin do\s*\n/m
|
21
26
|
else
|
22
27
|
route "root to: \"dashboard#show\"", namespace: [:madmin]
|
23
28
|
end
|
@@ -20,7 +20,7 @@ module Madmin
|
|
20
20
|
|
21
21
|
def generate_route
|
22
22
|
if route_namespace_exists?
|
23
|
-
route "resources :#{plural_name}", namespace: class_path, indentation: 4, sentinel: /namespace :madmin do\s*\n/m
|
23
|
+
route "resources :#{plural_name}", namespace: class_path, indentation: separated_routes_file? ? 2 : 4, sentinel: /namespace :madmin do\s*\n/m
|
24
24
|
else
|
25
25
|
route "resources :#{plural_name}", namespace: [:madmin] + class_path
|
26
26
|
end
|
@@ -46,6 +46,10 @@ module Madmin
|
|
46
46
|
def virtual_attributes
|
47
47
|
virtual = []
|
48
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
|
+
|
49
53
|
# Add virtual attributes for ActionText and ActiveStorage
|
50
54
|
model.reflections.each do |name, association|
|
51
55
|
if name.starts_with?("rich_text")
|
@@ -63,6 +67,9 @@ module Madmin
|
|
63
67
|
def redundant_attributes
|
64
68
|
redundant = []
|
65
69
|
|
70
|
+
# has_secure_password columns
|
71
|
+
redundant += model.attribute_types.keys.select { |k| k.ends_with?("_digest") }
|
72
|
+
|
66
73
|
model.reflections.each do |name, association|
|
67
74
|
if association.has_one?
|
68
75
|
next
|
@@ -98,13 +105,17 @@ module Madmin
|
|
98
105
|
if %w[id created_at updated_at].include?(name)
|
99
106
|
{form: false}
|
100
107
|
|
101
|
-
#
|
102
|
-
elsif
|
103
|
-
{index: false}
|
108
|
+
# has_secure_passwords should only show on forms
|
109
|
+
elsif name.ends_with?("_confirmation") || virtual_attributes.include?("#{name}_confirmation")
|
110
|
+
{index: false, show: false}
|
104
111
|
|
105
112
|
# Counter cache columns are typically not editable
|
106
113
|
elsif name.ends_with?("_count")
|
107
114
|
{form: false}
|
115
|
+
|
116
|
+
# Attributes without a database column
|
117
|
+
elsif !model.column_names.include?(name)
|
118
|
+
{index: false}
|
108
119
|
end
|
109
120
|
end
|
110
121
|
end
|