Using ActiveAdmin as a Backend in Rails 5 Application

Preparations

I will be using:

  • Ruby 2.4.0
  • Rails 5 with API key enabled
  • SQLite
  • ActiveAdmin

Preparing application:

1. Create a folder for application:

mkdir rails5_api_activeadmin
cd rails5_api_activeadmin

1

2. Create Gemset for application and install rails gem:

rvm use 2.4.0@rails5_api_activeadmin --ruby-version --create
gem install rails

2

3. Initialize a new git repository and generate a blank Rails 5 application:

git init
rails new . --api

3

4. Rails installed:

4

5. Adding IDE settings folder to .gitignore and committing changes:

5

6

6. Now launch a server and check if it’s working (I am launching it on port 3080, but the default is 3000):

rails s -p 3080

7

Database Models

This application will be used as a service for ordering food from local restaurants. So we need to have a few database models:

  • Dish (title, type, ingredients, description, price)

1. Scaffolding restaurant model

I will use built-in Rails scaffold generator and define fields, that have to be created in a database, providing field type. The default type is string, so it can be skipped. The model Dish will belong to model Restaurant and Restaurant can have many dishes. Also, I will use Enumerable on a dish type field.

rails g scaffold Restaurant title description
rails g scaffold Dish title dish_type:integer ingredients description price:decimal restaurant:belongs_to

8

We can ignore warnings in this case (rails code is not updated to the changes in Ruby 2.4.0).

And I used rails trick to tell, that model dish belongs to model Restaurant.

9

Now I have to tell that Restaurant has many dishes and set dishes type:

class Restaurant < ApplicationRecord
  has_many :dishes
end

class Dish < ApplicationRecord
  belongs_to :restaurant
  enum type: [:european, :pan_asian, :wok, :non_alcohol_drink, :alcohol_drink]
end

10

Enum will provide our application with automatically generated methods for dish type. And it will be saved in a database as an integer starting with 0 where each next number will correspond to a dish type. For example 0 for european, 1 for pan asian, 2 for wok

2. Migrating Database, configuring controllers and creating test data

Now I have to migrate the database and create dummy data:

rails db:migrate
rails c

Restaurant.create(title: 'First Restaurant', description: "It's first")
restaurant = Restaurant.first
restaurant.dishes.burger.create(title: 'Country Burger', ingredients: "beef steak, goat cheese, red pepper, salad,
onion, Italian balsamic glaze, olive oil, brioche bread bun, salt, pepper", description: 'Great burger', price: 2.99)

11

12

13

Now if I visit http://localhost:3080/restaurants or http://localhost:3080/dishes I will see data, stored in DB, in JSON format:

14

15

But I want to see all dishes that restaurant have on its page and restaurant name on a dishes page, so I have to make some changes to corresponding controllers:

class RestaurantsController < ApplicationController
  def show
    render json: @restaurant, include: 'dishes'
  end
end

class DishesController < ApplicationController
  def index
    @dishes = Dish.all
    render json: @dishes, include: 'restaurant'
  end
end

16

And I see updated info in JSON:

17

3. Setting up ActiveAdmin

First of all, I need to add required gems to Gemfile:

gem 'inherited_resources', github: 'activeadmin/inherited_resources'
gem 'activeadmin', '~> 1.0.0.pre4'
gem 'ransack', github: 'activerecord-hackery/ransack'
gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable'
gem 'formtastic', github: 'justinfrench/formtastic'
gem 'draper', github: 'audionerd/draper', branch: 'rails5', ref: 'e816e0e587'
gem 'activemodel-serializers-xml', github: 'rails/activemodel-serializers-xml'
gem 'jquery-ui-rails', '~> 5.0.4'

And install them:

bundle install

After that, we have to update app/controllers/application_controller from

class ApplicationController < ActionController::API
end

to

class ApplicationController < ActionController::Base
end

And config/application.rb

module NewApiApp
class Application < Rails::Application
# ...
config.middleware.use ActionDispatch::Flash
config.middleware.use Rack::MethodOverride
config.middleware.use ActionDispatch::Cookies
end
end

18

Now I will install ActiveAdmin. I won’t be using any authentication, so I skip them.

rails g active_admin:install --skip-users
rails db:migrate

When I visit http://localhost:3080/admin I see ActiveAdmin dashboard:

19

4. Creating and configuring ActiveAdmin resources

Now I have to generate ActiveAdmin resources:

It will add sections to create, list, update and delete dishes and restaurants, but default views and forms don’t satisfy my needs, so I will update them

First of all, I will update app/admin/restaurant.rb, so it shows restaurant dishes count on the index page and dishes list on the show page. And also I tell ActiveAdmin, which parameters can be changed:

ActiveAdmin.register Restaurant do
index do
column :title
column :description
column :dishes_count do |product|
product.dishes.count
end
actions
end
show do |restaurant|
attributes_table do
row :title
row :description
end
panel 'Dishes' do
table_for restaurant.dishes do |t|
t.column :title
t.column :dish_type
t.column :ingredients
t.column :description
t.column :price
end
end
end
permit_params :title, :description
end

After that, I will update dish edit form so I can choose dish type from the list. To do that, I have to create a form partial at app/views/admin/dishes/_form.html.erb:

<%= semantic_form_for [:admin, @dish], builder: Formtastic::FormBuilder do |f| %>
<%= f.semantic_errors %>
<%= f.inputs do %>
<%= f.input :restaurant_id, as: :select, collection: Hash[Restaurant.all.collect{|r| [r.title, r.id]}], include_blank: false %>
<%= f.input :title %>
<%= f.input :dish_type, as: :select, collection: Dish.dish_types.keys, include_blank: false %>
<%= f.input :description %>
<%= f.input :ingredients %>
<%= f.input :price %>
<% end %>
<%= f.actions %>
<% end %>

And render it from app/admin/dish.rb:

ActiveAdmin.register Dish do
  form partial: 'form'
  permit_params :restaurant_id, :title, :dish_type, :description, :ingredients, :price
end

Now I can create, read, update and destroy restaurants and dishes from application backend.

20

21

22

Conclusions

ActiveAdmin can be used if you need to implement backend for your database. It is flexible, customizable and can be easily integrated.

Got a project idea?

Master of Code designs, builds, and launches exceptional mobile, web, and conversational experiences.

















    By continuing, you're agreeing to the Master of Code
    Terms of Use and
    Privacy Policy and Google’s
    Terms and
    Privacy Policy

    Also Read

    All articles