excid3 / madmin Goto Github PK
View Code? Open in Web Editor NEWA robust Admin Interface for Ruby on Rails apps
Home Page: https://github.com/excid3/madmin
License: MIT License
A robust Admin Interface for Ruby on Rails apps
Home Page: https://github.com/excid3/madmin
License: MIT License
I don't like friendly_id overriding the find
method, so it would be awesome if Madmin could detect the FriendlyId
module on the model and automatically use Resource.friendly.find
instead of the normal Resource.find
This is purely a "nice to have", not something we should really prioritize.
We can find the store accessors easily with:
User.stored_attributes
#=> {:roles=>[:admin, :member]}
The values are the attributes we generate for Madmin resources.
The keys could probably be added to the list of ignored attributes.
My User
model uses has_secure_password
. This means it has a virtual attribute password
and it should be editable in madmin.
Currently, madmin doesn't understand this:
Couldn't find attribute or association 'password' with type '' on User model
Right now we have a hardcoded hash of column types and fields. Users will probably want to customize this, so we should make this something they can modify.
Registering scopes in a Resource can enable scope buttons for quick filtering on the index page.
class BlogPostResource < Madmin::Resource
scope :published
scope :draft
end
This would add All
, Published
and Draft
buttons to the top of the index.
Clicking on one would add ?scope=draft
to the URL.
The index action would add the scope with matching name.
def index
# Verify allowed scope name
scope_name = BlogPostResource.scopes.include?(params[:scope]) ? params[:scope] : :all
# Scope the resources
@resources = @resources.send(scope_name)
end
When running madmin with no changes the following resource is created for a paper_trail version resource:
class PaperTrail::VersionResource < Madmin::Resource
# Attributes
attribute :id, form: false
attribute :{ :null=>false }
attribute :event
attribute :whodunnit
attribute :object
attribute :created_at, form: false
attribute :transaction_id
attribute :object_changes
# Associations
attribute :version_associations
attribute :item
end
and gives the following errors when run:
Processing by Madmin::DashboardController#show as HTML
Completed 500 Internal Server Error in 167ms (ActiveRecord: 23.3ms | Allocations: 60500)
SyntaxError - syntax error, unexpected {, expecting literal content or terminator or tSTRING_DBEG or tSTRING_DVAR
attribute :{:null=>false}
^:
app/madmin/resources/paper_trail/version_resource.rb:4:in `'
ruby: 3.0.0
rails: 6.1.1
madmin: v0.1.1
definition:
t.citext :username, null: false, default: ''
t.inet :current_sign_in_ip
errors:
key not found: :inet
key not found: :citext
... and may be other postgresql types too(not tested)
Steps to repro:
bundle add madmin
rails g madmin:install
rails generate madmin:views
Expected:
Generator creates:
app/views/layouts/madmin/application.html.erb
app/views/madmin/application/_form.html.erb
app/views/madmin/application/_javascript.html.erb
app/views/madmin/application/_navigation.html.erb
app/views/madmin/application/edit.html.erb
app/views/madmin/application/index.html.erb
app/views/madmin/application/new.html.erb
app/views/madmin/application/show.html.erb
Actual:
- app/views/layouts/madmin/application.html.erb
app/views/madmin/application/_form.html.erb
- app/views/madmin/application/_javascript.html.erb
- app/views/madmin/application/_navigation.html.erb
app/views/madmin/application/edit.html.erb
app/views/madmin/application/index.html.erb
app/views/madmin/application/new.html.erb
app/views/madmin/application/show.html.erb
Running:
rails g madmin:views:navigation
and rails g madmin:views:layout
explicitly, generates navigation and layout views respectively.
Is it possible to install madmin in an engine (similar to this Godmin approach)?
Hi,
I install madmin and run rails g madmin:install with succes
But when I try to open /madmin (dashboard) I got this error :
"Webpacker::Manifest::MissingEntryError in Madmin::Dashboard#show"
Any idea?
Have this issue when i run rails g madmin:install command on a fresh rails installation (with MySql DB).
rails g madmin:install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Running via Spring preloader in process 15459
Traceback (most recent call last):
42: from -e:1:in `<main>'
41: from /home/dell/.rvm/rubies/ruby-2.6.5/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
40: from /home/dell/.rvm/rubies/ruby-2.6.5/lib/ruby/site_ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
39: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
38: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
37: from /home/dell/Bureau/madmin/bin/rails:9:in `<main>'
36: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
35: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
34: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
33: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
32: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
31: from /home/dell/.rvm/gems/ruby-2.6.5/gems/bootsnap-1.7.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
30: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/commands.rb:18:in `<main>'
29: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/command.rb:46:in `invoke'
28: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/command/base.rb:69:in `perform'
27: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
26: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
25: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
24: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/commands/generate/generate_command.rb:26:in `perform'
23: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/generators.rb:276:in `invoke'
22: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/base.rb:485:in `start'
21: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/group.rb:232:in `dispatch'
20: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:134:in `invoke_all'
19: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:134:in `map'
18: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:134:in `each'
17: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:134:in `block in invoke_all'
16: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
15: from /home/dell/.rvm/gems/ruby-2.6.5/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
14: from /home/dell/.rvm/gems/ruby-2.6.5/gems/madmin-1.0.0/lib/generators/madmin/install/install_generator.rb:11:in `eager_load'
13: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/application.rb:507:in `eager_load!'
12: from /home/dell/.rvm/gems/ruby-2.6.5/gems/railties-6.0.3.4/lib/rails/autoloaders.rb:30:in `each'
11: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:393:in `eager_load'
10: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:393:in `synchronize'
9: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:404:in `block in eager_load'
8: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:725:in `ls'
7: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:725:in `foreach'
6: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:733:in `block in ls'
5: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:409:in `block (2 levels) in eager_load'
4: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader.rb:409:in `const_get'
3: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:26:in `require'
2: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:26:in `tap'
1: from /home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:27:in `block in require'
/home/dell/.rvm/gems/ruby-2.6.5/gems/zeitwerk-2.4.2/lib/zeitwerk/loader/callbacks.rb:18:in `on_file_autoloaded': expected file /home/dell/Bureau/madmin/app/madmin/resources/action_text/rich_text_resource.rb to define constant ActionText::RichTextResource, but didn't (Zeitwerk::NameError)
Solution:
To resolv this issue, you have to read this link about Zeitwerk
https://stackoverflow.com/questions/57277351/rails-6-zeitwerknameerror-doesnt-load-class-from-module
We really like how Administrate does this and it's a nice way to go:
rails g madmin:views
should copy over app/views
from madmin so you can override the templates and add features.
Specific views
rails generate madmin:views:show
# -> app/views/admin/application/show.html.erb
Specific views for a resource
rails generate madmin:views:show User
# -> app/views/admin/users/show.html.erb
rails generate madmin:views:edit User
# -> app/views/admin/users/edit.html.erb
# -> app/views/admin/users/_form.html.erb
rails generate madmin:views:new User
# -> app/views/admin/users/new.html.erb
# -> app/views/admin/users/_form.html.erb
I’m opening this issue in relation to some of the trouble I ran into with #98. After more investigation I believe the error that can be raised in field_for_type
isn’t functioning quite as expected. Particularly the names being inserted into the error string don’t make sense. I believe it’s catching an error not expected by the original implementation.
I’ll continue to investigate and document my findings here when I get #98 finished.
For models that have relations, the forms provide fields that purport to reference a select
Stimulus controller: https://github.com/excid3/madmin/blob/master/app/views/madmin/fields/has_many/_form.html.erb#L4
These fields are not working for me. I believe they are supposed to be referencing a controller built into views/madmin/application/_javascript.html.erb
.
In my browser console, I'm seeing the following:
SyntaxError: Importing binding name 'Controller' is not found.
Any idea how to fix this?
I ran into following issue when pulling the latest master. Seems like latest commit is causing this issue.
Hi!
My issues are more questions about CRUD for users. I have users from devise that have password and password_confirmation. Unfortunately these are the fields that do not show up in the form for adding a new user. I understand that the only solution is to override the form
view for users
, and update
action in users_controller?
Second question is about Resources
. In a specific resource such as UserResource < Madmin::Resource
we declare attribute :id, form: false
. Is there somewhere a list of options that attribute can take, apart form: false/true
?
Third thought 😄 I think rails g madmin:field
does not work.
rails g madmin:field Custom
Running via Spring preloader in process 85728
Could not find generator 'madmin:field'. Maybe you meant "madmin:view"?
Run `bin/rails generate --help` for more options.
rails g --help
Madmin:
madmin:install
madmin:resource
madmin:view
madmin:views
madmin:views:edit
madmin:views:form
madmin:views:index
madmin:views:javascript
madmin:views:layout
madmin:views:navigation
madmin:views:new
madmin:views:show
There are times where I need to edit dozens or even hundreds of items at the same time. For example, updating a specific column to true
for many instances at a time. It would be amazing if madmin supported this.
When adding a reference to a model, I personally make an initial migration allowing null values for the model_id, fill the ids and only then force the null: false
on the id column.
However, this causes a NoMethodError on the display_name of a column. It is absolutely reasonable, but it makes the resource completely unavailable in that intermediate stage.
ActionView::Template::Error (undefined method `display_name' for nil:NilClass):
1: <% object = field.value(record) %>
2: <%= link_to Madmin.resource_for(object).display_name(object), Madmin.resource_for(object).show_path(object) %>
Perhaps it would make sense to somehow handle this use case?
Brand new Rails app w/ a few models generated
rails new {name} -T --database=postgresql
Ran through the docs for installation
rails s
in one tab, ./bin/webpack-dev-server
in another.
Unfortunately, I'm one of those old geezer Rails devs who's behind the times on Webpacker things.
Apologies if I'm missing something simple 😅
I'm receiving this error when trying to see the form for creating a new User.
I'll dig into it when I have a moment, for now I'm just dropping this issue on the repo to document what was happening. Something being skipped is coming back as an integer so I'll have to investigate why that's the cause. Actually taking a look at the screenshot again, I think the method just needs to be a little more type aware.
I generated a rails app rails new foobar --skip-javascript
and upon installing madmin it errors out when loading the dashboard because javascript_pack_tag is not defined.
Hi team,
I ran the install command on a semi changed jump start pro app. It builds out all the resources and seems to get the routes right however i get the error 'Zeitwerk::NameError in Madmin::DashboardController#show' saying it expected 'to define constant Resources::AccountInvitationResource, but didn't' - account invitation is the example here. Adding 'Resources::' to the class name just throws another error.
Any clues? A little wary of running install again unless there are other options to pass in?
First of all thanks for this great gem!
Right now the admin interface lives at /madmin
, and that is not customisable. I would like it at /admin
instead. This is doable by doing:
namespace :madmin, path: "admin"
This introduces a problem with the navigation. The resource paths are hard coded to /madmin
.
I can prepare a PR to generate the paths by the route name instead, if that's something you think is a good idea.
After updating Zeitwerk to 2.5.0.beta2
, Rails expects Madmin resources to be namespaced.
For example, madmin/resources/customer_resource
is expected to define Resources::CustomerResource
.
The actual error on build:
Zeitwerk::NameError: expected file /app/app/madmin/resources/customer_resource.rb to define constant Resources::CustomerResource, but didn't
Hi Chris and team!
In my project I'm using a custom FormBuilder that automatically adds certain Stimulus data-
properties around rich_text_areas
tags in order to support media attachment:
def rich_text_area(method, options = {})
default_opts = {data: {'trix-youtube-plugin-target': 'editor'}}
merged_opts = default_opts.merge(options)
@template.content_tag :div, data: {controller: 'trix-youtube-plugin'} do
@template.content_tag :div, data: {'trix-youtube-plugin-target': 'wrapper'} do
super(method, merged_opts)
end
end
end
Is there any easy way to reuse this form builder? Of course, I could just generate all the views and switch it myself but I didn't want to go that far (at least not yet).
ie. we use a to_param method in models to do friendly urls, we should make sure madmin doesn't break on those.
Looks like something is breaking with Skypack when trying to build stimulus-flatpickr
.
I originally encountered this error when trying to pull down updates to my fork so I could rebase #89 on top of it. I pulled down a fresh clone and confirmed that this is happening even on fresh installs.
It's breaking all Stimulus behavior, so I'll try and get this figured out so that Stimulus behavior isn't broken.
ruby: 3.0.0
rails: 6.1.1
madmin: v0.1.1
after rails g madmin:install
, madmin generator created following files:
controllers
├── madmin
│ ├── active_record
│ │ └── schema_migrations_controller.rb
│ ├── data_migrate
│ │ └── data_schema_migrations_controller.rb
│ └── users_controller.rb
madmin
└── resources
├── active_record
│ └── schema_migration_resource.rb
├── data_migrate
│ └── data_schema_migration_resource.rb
└── user_resource.rb
what are the purpose of these schema_migrations_* ? is this on purpose or bug? thanks
The seeds file has been quietly failing for a bit I think. I'm drawing up a commit to fix this right now. Going to cherry-pick it out of my current branch and open a PR here.
/usr/local/bundle/gems/activerecord-6.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:19:in `exec': PG::UndefinedTable: ERROR: relation "blazer_uploads" does not exist (ActiveRecord::StatementInvalid)
LINE 8: WHERE a.attrelid = '"blazer_uploads"'::regclass
Full stack trace below
Skipping ActionMailbox::InboundEmail because database table does not exist
/Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/inflector/methods.rb:288:in `const_get': uninitialized constant VideoCall::HabtmUsers (NameError)
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/inflector/methods.rb:288:in `block in constantize'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/inflector/methods.rb:284:in `each'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/inflector/methods.rb:284:in `inject'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/inflector/methods.rb:284:in `constantize'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/resource/resource_generator.rb:85:in `model'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/resource/resource_generator.rb:43:in `attributes'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/resource/templates/resource.rb.tt:3:in `template'
from /Users/ankur/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/erb.rb:905:in `eval'
from /Users/ankur/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/erb.rb:905:in `result'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/file_manipulation.rb:131:in `block in template'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:53:in `render'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:63:in `block (2 levels) in invoke!'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:63:in `open'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:63:in `block in invoke!'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/empty_directory.rb:117:in `invoke_with_conflict_check'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:60:in `invoke!'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions.rb:93:in `action'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/create_file.rb:25:in `create_file'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/actions/file_manipulation.rb:122:in `template'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/generators/named_base.rb:25:in `block in template'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/generators/named_base.rb:45:in `inside_template'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/generators/named_base.rb:24:in `template'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/resource/resource_generator.rb:13:in `generate_resource'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `block in invoke_all'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `each'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `map'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `invoke_all'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/group.rb:232:in `dispatch'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/generators.rb:275:in `invoke'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/madmin/generator_helpers.rb:4:in `call_generator'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/install/install_generator.rb:23:in `block in generate_resources'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/install/install_generator.rb:21:in `each'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/madmin-0.1.1/lib/generators/madmin/install/install_generator.rb:21:in `generate_resources'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `block in invoke_all'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `each'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `map'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:134:in `invoke_all'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/group.rb:232:in `dispatch'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/generators.rb:275:in `invoke'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/commands/generate/generate_command.rb:26:in `perform'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/command/base.rb:69:in `perform'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/command.rb:50:in `invoke'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/railties-6.1.1/lib/rails/commands.rb:18:in `<main>'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/zeitwerk-2.4.2/lib/zeitwerk/kernel.rb:34:in `require'
from /Users/ankur/Projects/OnDemandVideoVisit/bin/rails:5:in `<main>'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/bootsnap-1.5.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:59:in `load'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/commands/rails.rb:6:in `call'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/command_wrapper.rb:38:in `call'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application.rb:220:in `block in serve'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:10:in `block in fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:10:in `block in fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:26:in `fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:8:in `fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/activesupport-6.1.1/lib/active_support/fork_tracker.rb:26:in `fork'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application.rb:180:in `serve'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application.rb:145:in `block in run'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `loop'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application.rb:139:in `run'
from /Users/ankur/.rvm/gems/ruby-3.0.0/gems/spring-2.1.1/lib/spring/application/boot.rb:19:in `<top (required)>'
from <internal:/Users/ankur/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from <internal:/Users/ankur/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
from -e:1:in `<main>'
Hey guys, first contribution / issue here.
While being a newbie, I had some trouble setting up the app / foreman
initially due to lack of knowledge Re redis / sidekiq
I would love to add the below notes to the bottom of ReadMe to help noobs like me carry on with your template which I absolutely love as well as GoRails content, that helps me immensely!
App uses madmin
gem, so you need to run the madmin generator:
rails g madmin:install
This will install Madmin and generate resources for each of the models it finds.
brew update
brew install redis
brew services start redis
sudo apt-get install redis-server
Hi Chris,
App deploys successfully to heroku but crashes
$ heroku logs --tail reveals the following #deleted timestamps for clarity
heroku[worker.1]: Starting process with command sidekiq
heroku[worker.1]: State changed from starting to up
app[worker.1]: pid=4 tid=38s WARN: ArgumentError: Couldn't find attribute or association 'id' with type '' on Service model
app[worker.1]:
app[worker.1]: To fix this, either:
app[worker.1]: 1. Remove 'attribute id' from app/madmin/resources/service_resource.rb
app[worker.1]: 2. Or add the missing attribute or association to the Service model
app[worker.1]:
app[worker.1]: pid=4 tid=38s WARN: /app/vendor/bundle/ruby/2.7.0/gems/madmin-1.2.0/lib/madmin/resource.rb:152:in rescue in field_for_type' app[worker.1]: /app/vendor/bundle/ruby/2.7.0/gems/madmin-1.2.0/lib/madmin/resource.rb:36:in
attribute'
app[worker.1]: /app/app/madmin/resources/service_resource.rb:3:in <class:ServiceResource>' app[worker.1]: /app/app/madmin/resources/service_resource.rb:2:in
Any thoughts?
Much appreciated
Archie
: ERROR: relation "action_mailbox_inbound_emails" does not exist (PG::UndefinedTable) LINE 8: WHERE a.attrelid = '"action_mailbox_inbound_emails
Does the gem assume action_mailbox installed by default? This gets fixed after I run
rails action_mailbox:install
I love postgres array type. I tend to reach for it for any tagging system that isn't too complex. Most of all, I find it super fun to write code like this:
module Taggable
extend ActiveSupport::Concern
class Parser
def parse(tags)
case tags
when String
tags.split(/ *, */)
else
tags
end
end
end
def self.parser
@parser ||= Parser.new
end
module ClassMethods
def has_tags(*tag_def)
parser = Taggable.parser
tag_def.each do |tag_name|
scope :"with_any_#{tag_name}", ->(tags) { where("#{tag_name} && ARRAY[?]::varchar[]", parser.parse(tags)) }
scope :"with_all_#{tag_name}", ->(tags) { where("#{tag_name} @> ARRAY[?]::varchar[]", parser.parse(tags)) }
scope :"without_any_#{tag_name}", ->(tags) { where.not("#{tag_name} && ARRAY[?]::varchar[]", parser.parse(tags)) }
scope :"without_all_#{tag_name}", ->(tags) { where.not("#{tag_name} @> ARRAY[?]::varchar[]", parser.parse(tags)) }
define_method :"#{tag_name}=" do |value|
write_attribute tag_name,
case value
when String
value.split(",").map(&:strip)
else
value
end
end
define_method :"#{tag_name}_text" do
(read_attribute(tag_name) || []).join ","
end
self.class.class_eval do
define_method :"all_#{tag_name}" do |_options = {}, &block|
subquery = unscoped.select("unnest(#{tag_name}) as tag")
from(subquery).pluck(Arel.sql("distinct subquery.tag"))
end
define_method :"#{tag_name}_cloud" do |_options = {}, &block|
subquery =
unscoped
.select("unnest(#{tag_name}) as tag, count(*) as count")
.group(:tag)
.order(count: :desc)
from(subquery).pluck(Arel.sql("subquery.tag, subquery.count"))
end
end
end
end
end
end
I just sloppy pasted this from the internet; it does get it done, even if it isn't pretty.
The idea is to tag, for example, blog posts.
When playing around with the possibilities of doing this in Administrate, I discovered a few limitations that would be absolutely amazing if they could be ironed out in madmin.
If there is a way already, please let me know. Also, happy to contribute something if I can.
Test against everything:
See: https://github.com/excid3/noticed/blob/master/.github/workflows/ci.yml
The Stimulus controller in _javascript.html.erb
includes the new public class fields for targets
which Safari doesn't support yet.
Rails 6.1 includes draw
for separating routes. It would be nice to use this for storing all the admin routes in a separate file.
For backwards compatibility, we could check the Rails version and fallback to inserting into the main routes file. Although I don't see much need to support Rails 6.0 or earlier.
The encrypted attributes use a _digest
column to store the encrypted values. We can ignore these columns, but add attributes to the Madmin resource for the attribute.
We need a couple tools like Flatpickr, slimselect, etc to make the admin more useful, plus CSS for styling the admin.
The goals here:
It would be great if we could use something like Skypack CDN so that we didn't have to integrate with the Asset Pipeline or Webpacker. A user could then edit the layout to include their own JS.
If not, I think a good option is to actually provide two generators to install assets into your app (one for the asset pipeline, one for webpacker).
We could add app/javascript/packs/madmin.js
and dependencies if webpacker is installed. And the same for app/assets/javascripts/madmin.js
for the asset pipeline. We would have to install dependencies along with this approach though.
I'd like Madmin to fully support both Turbolinks & Hotwire, so Stimulus controllers are ideal here.
We're also currently using TailwindCSS for styling. This comes from a CDN, but it is a heck of a lot of CSS.
We could purge and ship only what we need as part of the gem and let users add their own CSS from the asset pipeline or webpacker.
I'd love to switch from Adminstrate but I can't do that until Madmin has search 🙏
Exception on a new Rails app, models with decimal fields
# Attributes
attribute :id, form: false
attribute :price
attribute :complete
attribute :created_at, form: false
attribute :updated_at, form: false
You can access the validators on a model by doing:
User._validators
We can use this to render an asterisk or note for required fields.
User._validators[:email].any? { |v| v.is_a? ActiveModel::Validations::PresenceValidator }
Todos:
required?
method on Field* Required
label when rendering fields👋
Something that would be good to document is how applications can implement a level of authentication for Madmin. Out of the box we produce an unauthenticated view, this is obviously not production ready.
Because authentication can be different from app to app, we'd prefer to not roll our own and to instead allow Developers to use their existing models instead.
What we'd like to see is:
Let us know if there's more information needed!
It would be great to support nested fields.
It appears Administrate has a plugin for this as well: https://github.com/nickcharlton/administrate-field-nested_has_many
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.