Search code examples
ruby-on-railscsvactiveadminsidekiqdashboard

Rails Active Admin: How to add a CSV uploader action on dashboard page


I am working on a project where I have a CSV uploader class method import_listings(file) which is being called by Sidekiq perform method.

class CsvWorker

    include Sidekiq::Worker 
    sidekiq_options retry: false

    def perform(file)
        #call import listings class method on the file.     
        imported = Listing.import_listings(file)
        # return true   
    end
end

I am calling the perform_async in a controller action index as shown:

def import
  @imported = CsvWorker.perform_async(params[:file].path)       
end

Everything works great!

I want to move this method on the backend, in the active admin dashboard page. As shown in the figure below. There would be columns for different CSV uploads each with a file upload form :

enter image description here

A member action won't be best suited for this task because there is no particular resource. It's a dashboard page.

The code for the dashboard is as below:

ActiveAdmin.register_page "Dashboard" do

  menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") }

  content title: proc{ I18n.t("active_admin.dashboard") } do

    div class: "blank_slate_container", id: "dashboard_default_message" do
      span class: "blank_slate" do
        span "Welcome To Want A Car Buy A Car Backend!"        
        small "Use options below for CSV below:"   
      end
    end
   end # content     
end

The problem is if I try to add a form action in the column like below, it gives me an error saying I can't add inside the column:

columns do
      column do
        panel "CSV Uploads for Dealers" do
          ul do
             form_tag import_listings_path, multipart: true do
                file_field_tag :file 
                submit_tag "Import Csv" 
            end
          end
        end
      end

My question is: how can I add a file upload form in these columns, which will call the sidekiq method and pass file params to it? Where to define the method in the dashboard page? There is no controller on the page right? I don't want to add it to the admin resource files. I want it on the dashboard page.


Solution

  • In ActiveAdmin, when we want to render some data on a page that is not tied to any resource, Custom Pages give you that option. Dashboard is such an example which we define as: ActiveAdmin.register_page 'Dashboard'.

    A custom page gives you a bare-metal controller and routes as you need. It also enables you to render any partials and page actions too. These page actions will have corresponding named routes too to be accessible with route helpers. You are free to invoke any outside model methods from those actions to accomplish any task.

    Knowing all these, let's define a page action which will receive the uploaded file, process it and then redirect to the dashboard page.

    # app/admin/dashboard.rb
    
    page_action :import_listings, method: :post do
      # set a breakpoint here to check if you receive the file inside params properly
      CsvWorker.perform_async(params[:file].path)
      # do anything else you need and redirect as the last step
      redirect_to admin_dashboard_path
    end
    

    At this point, :import_listings action will have a named route as admin_dashboard_import_listings.

    Now we need to refer to this action upon form submission. Let's put the form block inside a partial:

    <!-- app/views/admin/dashboard/_import_listings.html.erb -->
    
    <%= form_tag admin_dashboard_import_listings_path, multipart: true do %>
      <%= file_field_tag 'file', accept: 'text/csv' %>
      <%= submit_tag 'Import Csv' %>
    <% end %>
    

    Finally render this partial inside the content block:

    # app/admin/dashboard.rb
    
    content do
      ...
      columns do
        column do
          panel 'CSV Uploads for Dealers' do
            ul do
              render 'admin/dashboard/import_listings'
            end
          end
        end
      end
      ...
    end
    

    Now you will be able to render that form in the dashboard, upload files, submit, handle the uploads in background jobs and finally redirect to the dashboard or anywhere you want.

    Enjoy!