Підготовка
Я буду використовувати:
- Ruby 2.4.0
- Rails 5 з увімкненим API-ключем
- SQLite
- ActiveAdmin
Підготовка додатку:
- Створіть папку для додатку:
mkdir rails5_api_activeadmin
cd rails5_api_activeadmin
- Створіть Gemset для додатку та встановіть gem rails:
rvm use 2.4.0@rails5_api_activeadmin --ruby-version --create
gem install rails
- Ініціалізуйте новий git-репозиторій та згенеруйте порожній додаток Rails 5:
git init
rails new . --api
- Rails встановлено:
- Додаємо папку налаштувань IDE до .gitignore та комітимо зміни:
- Тепер запустіть сервер і перевірте, чи працює він (я запускаю на порту 3080, але за замовчуванням — це 3000):
rails s -p 3080
Моделі бази даних
Цей додаток буде використовуватися як сервіс для замовлення їжі з місцевих ресторанів. Тому нам потрібно створити кілька моделей бази даних:
- Страва (назва, тип, інгредієнти, опис, ціна)
- Ресторан (назва, опис)
- Генерація ресторанної моделі
Я буду використовувати вбудований генератор scaffold у Rails і визначатиму поля, які потрібно створити в базі даних, вказуючи тип поля. За замовчуванням тип — рядок, тому його можна пропустити. Модель Dish буде належати до моделі Restaurant, і Restaurant може мати багато страв. Також я використаю Enumerable для поля типу страви.
rails g scaffold Restaurant title description
rails g scaffold Dish title dish_type:integer ingredients description price:decimal restaurant:belongs_to
Ми можемо проігнорувати попередження в цьому випадку (rails код ще не оновлений під зміни в Ruby 2.4.0).
Я використав трюк Rails, щоб вказати, що модель dish належить до моделі Restaurant.
Тепер мені потрібно вказати, що Restaurant має багато страв, та встановити типи страв:
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
Enum надасть нашому додатку автоматично згенеровані методи для типу страви. І він буде збережений в базі даних як ціле число, починаючи з 0
, де кожне наступне число відповідатиме типу страви. Наприклад: 0 для європейської
, 1 для паназійської
, 2 для вок
тощо.
2.
Міграція бази даних, налаштування контролерів і створення тестових даних
Тепер я маю мігрувати базу даних і створити тестові дані:
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)
Тепер, якщо я відвідаю http://localhost:3080/restaurants
або http://localhost:3080/dishes
, я побачу дані, збережені в базі даних, у форматі JSON:
Але я хочу бачити всі страви, які ресторан має на своїй сторінці, а на сторінці страв – назву ресторану. Тому потрібно зробити деякі зміни в відповідних контролерах:
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
І тепер я бачу оновлену інформацію у форматі JSON:
Налаштування ActiveAdmin
Перш за все, мені потрібно додати необхідні gems до 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'
І встановіть їх
bundle install
Після цього потрібно оновити app/controllers/application_controller
, змінюючи:
class ApplicationController < ActionController::API
end
на
class ApplicationController < ActionController::Base
end
І 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
Тепер я встановлюю ActiveAdmin. Я не буду використовувати жодну аутентифікацію, тому пропускаю цей крок.
rails g active_admin:install --skip-users
rails db:migrate
Коли я відвідаю http://localhost:3080/admin
, я бачу панель інструментів ActiveAdmin:
Створення та налаштування ресурсів ActiveAdmin
Тепер я маю створити ресурси ActiveAdmin:
rails g active_admin:resource Restaurant
rails g active_admin:resource Dish
Це додасть розділи для створення, перегляду, оновлення та видалення страв і ресторанів, але стандартні вигляди та форми не відповідають моїм потребам, тому я оновлю їх.
По-перше, я оновлюю app/admin/restaurant.rb
, щоб на сторінці індексу відображалася кількість страв ресторану та список страв на сторінці перегляду.
Також я вказую ActiveAdmin, які параметри можна змінювати:
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
Після цього я оновлю форму редагування страви, щоб я міг вибирати тип страви зі списку. Для цього потрібно створити частину форми в 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 %>
І рендерити її з app/admin/dish.rb
:
ActiveAdmin.register Dish do
form partial: 'form'
permit_params :restaurant_id, :title, :dish_type, :description, :ingredients, :price
end
Тепер я можу створювати, читати, оновлювати та видаляти ресторани та страви з бекенду додатку.
Висновки
ActiveAdmin можна використовувати, якщо потрібно реалізувати бекенд для вашої бази даних. Він гнучкий, настроюваний і легко інтегрується.
Оригінально опубліковано на masterofcode.com/blog
Master of Code пропонує повний спектр послуг з розробки та дизайну інтегрованих веб-, мобільних та чат-бот рішень. Наш великий досвід у різних бізнес-сферах, включаючи освіту, медицину та електронну комерцію, дозволяє нам запропонувати рішення, яке підійде саме для вашого бізнесу. Ми завжди готові допомогти якщо ми можемо зробити щось для вас.
Перекладено з: Using ActiveAdmin as a backend in Rails 5 application