Administrate: How can I create a new Dashboard without a model?

Created on 7 Mar 2016  路  21Comments  路  Source: thoughtbot/administrate

I want to create a new dashboard for creating new database entries with mixed fields from different models. In my case it's a new Book with matching Authors and Recipes. All of them have models and dashboards, but I need a new create method to create a book with multiple authors and multiple recipes on one page.

I tried adding a new FOO_dashboard.rb and FOO_controller.rb file with a matching route. But I get an error uninitialized constant FOO after that.

How would I do this?

Most helpful comment

Is there a plan to implement official support for this? Having pages in dashboards that are NOT directly related to specific model is a pretty common pattern.

All 21 comments

Overwrite the crud actions in controller.

I don't want to overwrite something because I need the already created actions ;)

ok then i think the problem is here (without knowledge of code)...

Administrate::Search for index
find_resource aka resource_resolver method in Administrate::ApplicationController

i think this is easy to do and not too much of work...

just create the controller

class Admin::DashboardsController < Administrate::ApplicationController
  def index
  end
end

and add route

namespace :admin do
  resources :dashboards, only: [:index]
end

thats it. you also do not need to create a Dashboard manifest class. I use a patched version of administrate but this part should also work in default version.

I think this is a regression in 0.1.4 and also exists in 0.1.5. It related to #481 with a possible fix in #514.

I have the following:

routes.rb

namespace :admin do
   ...
   root controller: :welcome, action: :index
end

app/controllers/admin/welcome_controller.rb

module Admin
  class WelcomeController < Admin::ApplicationController
    def index
    end
  end
end

And I also have app/views/admin/welcome/index.html.haml.

In 0.1.3 this works fine. I go to /admin and I see that controller. In 0.1.4 I get the uninitialized constant.

/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb:261:in `const_get'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb:261:in `block in constantize'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb:259:in `each'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb:259:in `inject'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/inflector/methods.rb:259:in `constantize'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
/home.gem/ruby/2.3.0/gems/administrate-0.1.5/app/helpers/administrate/application_helper.rb:12:in `display_resource_name'
/home.gem/ruby/2.3.0/gems/administrate-0.1.5/app/views/administrate/application/_sidebar.html.erb:14:in `block in __home_gem_ruby_______gems_administrate_______app_views_administrate_application__sidebar_html_erb___4067084401634909320_70144335177260'
/home.gem/ruby/2.3.0/gems/administrate-0.1.5/app/views/administrate/application/_sidebar.html.erb:11:in `each'
/home.gem/ruby/2.3.0/gems/administrate-0.1.5/app/views/administrate/application/_sidebar.html.erb:11:in `__home_gem_ruby_______gems_administrate_______app_views_administrate_application__sidebar_html_erb___4067084401634909320_70144335177260'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/template.rb:145:in `block in render'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `block in instrument'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `instrument'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/template.rb:333:in `instrument'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/template.rb:143:in `render'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb:339:in `render_partial'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb:310:in `block in render'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/abstract_renderer.rb:39:in `block in instrument'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `block in instrument'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/home.gem/ruby/2.3.0/gems/activesupport-4.2.6/lib/active_support/notifications.rb:164:in `instrument'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/abstract_renderer.rb:39:in `instrument'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/partial_renderer.rb:309:in `render'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/renderer/renderer.rb:51:in `render_partial'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/helpers/rendering_helper.rb:35:in `render'
/home.gem/ruby/2.3.0/gems/haml-4.0.7/lib/haml/helpers/action_view_mods.rb:12:in `render_with_haml'
/home.gem/ruby/2.3.0/gems/administrate-0.1.5/app/views/layouts/administrate/application.html.erb:31:in `__home_gem_ruby_______gems_administrate_______app_views_layouts_administrate_application_html_erb___185022205874595341_70144330401780'
/home.gem/ruby/2.3.0/gems/actionview-4.2.6/lib/action_view/template.rb:145:in `block in render'
...

I started down the road of making a stub Welcome class but Administrate wants to generate links and such, so I stopped that.

When I did this I found I didn't need to stub too much to make it work. I had a controller called StatsController and this 'model':

class Stat
  def self.model_name
    self
  end

  def self.human(*args)
    "Statistics"
  end

end

@jalada - How did you get it to work as I'm seeing the same error that @swalberg received?

I've got get 'business', to: 'admin_business#index' in my admin namespace in routes.rb, and a placeholder Business model, but in the _navigation partial, it's giving me uninitialized constant AdminBusiness.

I'd appreciate some guidance on how to get a custom page into the administrate dashboard that doesn't require a placeholder model. I'm also hoping to wrap the sidekiq admin layout view with administrate but that's not terribly important.

Update: Just realized it should have been get 'business', as: 'business', to: 'business#index'. Crisis averted, but I'd still like to have a kosher approach to entirely custom pages.

@archonic Do you have any thoughts on what that might look like?

Off the top of my head, I was thinking about perhaps a model you could subclass which helped with some of the Administrate assumptions, but you'd still need a stub model then.

I suppose a generalized model would make things a bit easier. Having to build a fake model at all is a bit weird in my mind. At one point I was picturing a dashboard manifest solution where you could inherit from something like Administrate::CustomDashboard and that wouldn't look for an associated model, but just serve a specified controller and action in the administrate layout. That should also be able to solve the issue of getting the Sidekiq dashboard within administrate in a nice generalized way as well.

Mmm, I like that! It solves the problem more broadly which is good.

I'd love to see a PR attacking this, so shout if I can help any further.

Another workaround it to overwrite navigation partial, with this approach, we don't need to build a fake model:

app/views/admin/application/_navigation.html.erb

<nav class="navigation" role="navigation">
  <% Administrate::Namespace.new(namespace).resources.each do |resource| %>
    <% next if resource.resource == 'pages' %>
    <%= link_to(
      display_resource_name(resource),
      [namespace, resource.path],
      class: "navigation__link navigation__link--#{nav_link_state(resource)}"
    ) %>
  <% end %>
  <%= link_to 'Hello', admin_hello_path, class: "navigation__link navigation__link--#{action_name == 'hello' ? 'active' : 'inactive'}" %>
  <%= link_to 'World', admin_world_path, class: "navigation__link navigation__link--#{action_name == 'world' ? 'active' : 'inactive'}" %>
</nav>

config/routes.rb

Rails.application.routes.draw do
  namespace :admin do
    root to: 'pages#home'
    controller 'pages' do
      get 'hello'
      get 'world'
    end
    resources :posts
    resources :tags
  end
end

Is there a plan to implement official support for this? Having pages in dashboards that are NOT directly related to specific model is a pretty common pattern.

+1

+1

+1

Any solution for this?

+1

Another workaround it to overwrite navigation partial, with this approach, we don't need to build a fake model:

app/views/admin/application/_navigation.html.erb

<nav class="navigation" role="navigation">
  <% Administrate::Namespace.new(namespace).resources.each do |resource| %>
    <% next if resource.resource == 'pages' %>
    <%= link_to(
      display_resource_name(resource),
      [namespace, resource.path],
      class: "navigation__link navigation__link--#{nav_link_state(resource)}"
    ) %>
  <% end %>
  <%= link_to 'Hello', admin_hello_path, class: "navigation__link navigation__link--#{action_name == 'hello' ? 'active' : 'inactive'}" %>
  <%= link_to 'World', admin_world_path, class: "navigation__link navigation__link--#{action_name == 'world' ? 'active' : 'inactive'}" %>
</nav>

config/routes.rb

Rails.application.routes.draw do
  namespace :admin do
    root to: 'pages#home'
    controller 'pages' do
      get 'hello'
      get 'world'
    end
    resources :posts
    resources :tags
  end
end

How is the PagesController being structured/modified? I'm following your solution but seems like the navigation doesn't seem to work. resource actually returns 'dashboard' when I create a page named 'dashboard':

module Admin
  class PagesController < Admin::ApplicationController
    def dashboard

    end
  end
end
namespace :admin do
  resources :posts

  controller :pages do
    get :dashboard
  end

  root controller: :dashboard, action: :index
 end

@atomtigerzoo, is this still an issue for you?

@atomtigerzoo, is this still an issue for you?

No, but thank you for asking :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

trandoanhung1991 picture trandoanhung1991  路  3Comments

gracewashere picture gracewashere  路  3Comments

steffenix picture steffenix  路  4Comments

rmarronnier picture rmarronnier  路  4Comments

drewtunney picture drewtunney  路  3Comments