It is expected that you follow on from a previous setup like the one explored in my previous blog post "ActiveAdmin With Ruby On Rails 7".
Getting started
It is expected that you follow the "Getting Started" section from my previous post "ActiveAdmin With Ruby On Rails 7" (but for a project named demo-upload-csv-to-active-admin).
Once you are at the point of seeing the /admin route from that post, come back here to finish the rest.
The last things that we want to do:
Create a Template model (that we will populate in the database from a CSV file).
Create a page for our CSV upload.
Create a file for our CSV helper file.
Create a CSV file for our test upload.
# Create our "Template" model
$ bin/rails g model Template name:string description:string author:string
# Create a page for our CSV upload
$ touch app/admin/templates.rb
# Create a service folder for the CSV converter
$ mkdir app/services
$ touch app/services/csv_helper.rb test.csv
# Migrate changes for our template
$ bin/rails db:migrate
At this stage, our project is now ready to start populating.
Updating our Template model
We will add some simple validations for our file app/models/template.rb here:
class Template < ApplicationRecord
validates :name, presence: true
validates :description, presence: true
validates :author, presence: true
end
Setting our CSV data
Our CSV data will map to our name, description and author columns respectively.
The idea is that each row will end up populating the data.
Writing out our admin template page
In app/admin/templates.rb, we will register a page "Template":
ActiveAdmin.register_page 'Template' do
action_item only: :index do
link_to 'Upload CSV', action: 'upload_csv'
end
page_action :upload_csv do
render 'admin/csv/upload_csv'
end
page_action :import_csv, method: :post do
templates = CsvHelper.convert_to_templates(params[:dump][:file])
Template.transaction do
templates.each(&:save!)
end
redirect_to({ action: :index }, notice: 'CSV imported successfully!')
rescue StandardError
redirect_to({ action: :index },
flash: { error: 'CSV imported failed! Check the template is correct or contact a developer.' })
end
end
There are a few things that we are doing here:
Creating a page at the route /admin/template.
Adding a link to the page at the top of the page for uploading a CSV that will redirect to admin/template/upload_csv.
The route admin/template/upload_csv will render the app/views/admin/csv/upload_csv.html.erb view (that we will create next).
The page_action method will be called when the user clicks on the link to upload a CSV.
The last action is most important. It will attempt to convert our CSV file to Template instances and then a transaction will attempt to upload them to the database (which we will also create soon).
If successful, the user will be redirected back to /admin/template with a success banner message displayed.
If the user is unsuccessful, the user will be redirected back to /admin/template with a failure banner message.
Next, let's tackle the view.
Creating our upload CSV view
Create the file app/views/admin/csv/upload_csv.html.erb and add the following:
The above code will create a form that allows for a file, then on submission uploads that to the /admin/template/import_csv route that we have our handler for.
Finally, we need to add in the CsvHelper class.
Adding the CsvHelper class
Under app/services/csv_helper.rb, add the following:
class CsvHelper
class << self
def convert_to_templates(csv_data)
templates = []
csv_file = csv_data.read
CSV.parse(csv_file) do |row|
name, description, author = row
templates << Template.new(name: name, description: description, author: author)
end
templates
end
end
end
Here we are adding a class method to the CsvHelper class. This method takes CSV data from the upload, converts each row to a Template instance, pushes it to an array of templates and finally returns it.
The returned templates will start a transaction for them to be inserted (as you can see in the previous code for the form submission handler).
Testing the CSV upload
At this point, we can get to our admin panel and test things out.
Run bin/rails s to start the server, head to /admin and login with the admin@example.com and password details.
Once logged in, you can head to /admin/template and click on the Upload CSV link.
Template page
The following page will display the form for your CSV file upload.
Template form for the file upload
Once you select the test.csv file that we created, you will be redirected to the /admin/template/import_csv route with a success message (unless there is an issue).
Success
If you have an issue, you will see the error message:
Error
Summary
Today's post demonstrated how to upload a file to ActiveAdmin and process that upload.