Очень часто, почти всегда, хочется сократить до максимума время/усилия на создание «админки».
Тем более когда уже все модели в строю и хочется дать клиенту возможность работать с ними,
добавлять записи, редактировать, удалять, редактировать зависимости итд.
Обычно на рутинный процесс создания этого интерфейса уходит непростительно много времени/ресурсов.
Кроме случая когда используются уже готовые наработки.
Именно к таким наработкам относится и Rear.
С его помощью можно создать полноценный админ интерфейс одной строкой — include Rear
Согласен, звучит как SEO-шное заявление, но тем не менее это так.
Полный разбор полёта под катом.
А для нетерпеливых — смотрим демо
Допустим у нас имеется модель Article
и нужно за-CRUD-ить записи:
запускаем приложение:
и получаем вот такой вот интерфейс:
Панель обзора
Редактирование
Удобно, но не совсем практично.
Во первых редактировать HTML в textarea как минимум нецелесообразно.
Для исправления ситуации устанавливаем rear-ckeditor
и добавляем input :content, :ckeditor, что превратит textarea в удобный Rich Text Editor.
Можно также установить rear-ace
и использовать input :content, :ace если нужен Ace вместо CKEditor.
Во вторых надо дать людям возможность фильтрации записей.
Для этого добавляем filter :name.
В третих модели редко бывают одиноки, обычно они идут с различными зависимостями.
В нашем случае Article
зависит от Category
, так что просто добавляем модель Category
а остальное сделает Rear
:
и получаем:
дополнительный фильтр:
Rich Text Editor:
редактирование зависимостей:
Установить Rear можно через gem install rear
Попробовать у себя можно скопировав и запустив код ниже.
Наверное не стоит отмечать что нужно также установить data_mapper
и dm-mysql-adapter
и до первого запуска выполнить DataMapper.auto_migrate! для создания таблиц, после создания самой базы разумеется.
require 'rear'
require 'rear-ckeditor'
require 'data_mapper'
require 'dm-mysql-adapter'
class Article
include DataMapper::Resource
include Rear # вежливо просим Rear построить интерфейс
input :content, :ckeditor
filter :name
property :id, Serial
property :name, String
property :content, Text
has n, :categories, through: Resource
end
class Category
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :articles, through: Resource
end
DataMapper.finalize
DataMapper.setup :default, 'mysql://dev@localhost/dev__rear_habrahabr'
Rear.run server: :Thin, port: 2424
А отсюда по подробнее.
Что это такое и с чем его едят?
Это тот-же ActiveAdmin
только не для Rails а для Espresso Framework.
Насколько реально использовать Rear
в реальном проекте?
Rear ничего от вас не требует, он абсолютно прозрачно интегрируется с новым или существующим проектом.
Он всего-лишь добавляет несколько методов в нужные модели, никак не влияя на остальные части приложения.
Насколько реально настроить интерфейс под свои нужды?
По умолчанию Rear использует тот-же интерфейс для всех приложений.
Если нужен custom интерфейс для определённого приложения, устанавливаем шаблоны к себе в приложение и редактируем.
Теперь все модели будут использовать интерфейс приложения. Если определённая модель требует собственного интерфейса,
создаём папку с именем модели и ставим туда нужные шаблоны.
Приступаем к усвоению
Для начала нужно всего-лишь «инклудить» Rear в нужные модели:
class Foo < ActiveRecord::Base
include Rear
end
primary_key
Дальше, для правильной работы, Rear-у нужен первичный ключ модели.
Он попытается сам определить pkey и обычно он с этим справляется.
Для исключительных случаев нужно задать pkey в ручную.
Делается это через `primary_key`:
primary_key :ItemID
order_by
По умолчанию Rear выведет записи в том порядке в котором они выдаются ORM.
Когда нужно выводить в определённом порядке, задаём столбцы через `order_by`:
`ActiveRecord`:
order_by 'name, id DESC'
`DataMapper`:
order_by :name, :id.desc
items_per_page
По умолчанию Rear выводит по десять записей на каждую страницу.
Изменить это можно через `items_per_page`:
items_per_page 50
menu_label / menu_position / menu_group
Для лёгкой навигации по администрированым моделям Rear создаст верхнее меню
со списком всех моделей.
По умолчанию будет использоватся имя модели, но это можно изменить через `menu_label`:
class PageModel < ActiveRecord::Base
include Rear
menu_label :Pages
# ...
end
Позиционироваться модели будут в порядке определения.
Если использовать `menu_position`, можно изменить порядок вывода моделей в меню:
class City < ActiveRecord::Base
include Rear
menu_position 100
end
class Country < ActiveRecord::Base
include Rear
menu_position 1000
end
class State < ActiveRecord::Base
include Rear
menu_position 500
end
Это создаст меню вида `Country | State | City` вместо дефолтного `City | Country | State`.
Довольно часто модели сортированы по группам.
Группировать их можно также и в меню Rear-а, если использовать `menu_group`:
class City < ActiveRecord::Base
include Rear
menu_group :Location
end
class Country < ActiveRecord::Base
include Rear
menu_group :Location
end
class State < ActiveRecord::Base
include Rear
menu_group :Location
end
Это создаст всего один пункт меню — Location — при наведении на котором
появятся 3 под-пункта — City, Country и State.
readonly!
Иногда нужно отображать ту или иную модель в режиме только для чтения.
Это легко делается через `readonly!`:
class City < ActiveRecord::Base
include Rear
readonly!
end
Теперь города можно будет просматривать без возможности редактирования.
Столбцы
Rear сам найдёт все столбцы и создаст HTML тэги для каждого в соответствии с типом столбца.
Следующие типы столбцов отображаются автоматически:
:string
:text
:date
:time
:datetime
:boolean
Следующие типы надо задавать в ручную:
:ckeditor
:ace
:radio
:checkbox
:select
:password
Для отображения столбца определённого типа используется метод `input`.
Первым аргументом идёт имя столбца а тип идёт вторым:
class Foo < ActiveRecord::Base
include Rear
input :content, :ckeditor
end
Явное определение столбцов иммет смысл только если нужен custom тип
или нужно передать HTML атрибуты(class, style etc.) или блок для тонкой настройки.
label
По умолчанию, в качестве метки, Rear использует имя столбца.
Более информативную метку можно задать через `label`:
class Foo < ActiveRecord::Base
input :date, label: 'Select date please'
# or
input :date do
label 'Select date please'
end
end
Radio/Checkbox/Select
Radio/Checkbox/Select столбцы нуждаются в блоке для корректной работы:
Внутри блока надо задать список опций в виде Array или Hash.
Задаются опции через метод `options`.
Если значения используются также в качестве меток, можно использовать Array:
input :color, :select do
options 'Red', 'Green', 'Blue'
end
Если же метки отличаются, используем Hash:
input :color, :radio do
options 'r' => 'Red', 'g' => 'Green', 'b' => 'Blue'
end
Radio и single-Select столбцы отправят данные в виде строки.
А вот Checkbox и multi-Select отправят Array.
Если ORM не совсем корректно преобразовывает Array в строку,
надо установить хук для преобразования перед отправкой.
Делается это через `on_save` метод:
input :color, :checkbox do
options 'r' => 'Red', 'g' => 'Green', 'b' => 'Blue'
end
on_save do
params[:color] = params[:color].join(',')
end
Теперь цвета отправляются в виде строки.
Но теперь интерфейс не выделит ни одну опцию, создавая впечатление что цвета не были сохранены.
Это потому что ни ORM ни Rear не знают как правильно преобразовать строку в Array.
Исправляется это с помощью метода `options`, задав блок который преобразует строку в Array:
input :color, :checkbox do
options 'r' => 'Red', 'g' => 'Green', 'b' => 'Blue' do
item.color.split(',')
end
end
on_save do
params[:color] = params[:color].join(',')
end
Блок имеет доступ к обьекту через `item` и может делать с ним всё что угодно.
В данном случае нам всего-лишь надо преобразовать цвета в Array — `item.color.split(',')`
Блок всегда должен возвращать Array из выбранных значений, даже если сам метод `options` использует Hash.
Rich Text Editor
По умолчанию Rear использует textarea для Text столбцов.
Если нужно превратить textarea в полноценны HTML редактор, устанавливаем rear-ckeditor
и ставим тип столбца в ckeditor
:
class MyModel < ActiveRecord::Base
include Rear
input :content, :ckeditor
end
На данный момент Rear использует CKEditor 4й версии.
Если внутри редактора нужно иметь возможность выбирать/загружать картинки,
используем также метод `public_path`, задав путь к папке с картинками:
input :content, :ckeditor do
public_path '../public/images'
end
readonly / disabled
Иногда нужно отображать определённые столбцы в режиме только для чтения.
Делается это через опцию `readonly`:
input :visits, readonly: true
Важно отметить что readonly эффективен только при редактировании существующих записей.
При создании новых записей readonly столбцы вполне редактируемы.
Если нужно отключить редактирование также при создании новых записей, испрользуем опцию `disabled`:
input :visits, disabled: true
Если же нужно совсем отключить определённый столбец, так чтобы не отображался и не был включён в набор данных, ставим опцию `editor` в false:
input :visits, editor: false
Если нужно исключить столбец также со страниц обзора, ставим опцию `pane` в false:
input :visits, pane: false
row
По умолчанию Rear отображает каждый столбец в собственном ряду — один столбец, один ряд.
Если нужно поставить несколько столбцов в один ряд, используем опцию `row`:
input :red, row: :Colors
input :green, row: :Colors
input :blue, row: :Colors
Можно также использовать метод `row` с блоком:
row :Colors do
input :active
input :published
input :archived
end
Если ряд не нуждается в метке, `row` можно вызывать без аргументов.
HTML атрибуты
Когда столбец нуждается в дополнительных атрибутах, передаём их в виде опций:
input :short_text, style: "height: 400px;"
# or
input :short_text do
html_attrs style: "height: 400px;"
end
Отображение данных
По умолчанию Rear отобразит значение столбца в том виде в котором они пришли из ORM.
Когда значение нужно преобразить, используем метод `value` внутри блока:
input :created_at do
value { item.created_at.strftime('%d %m, %Y') }
end
Важно отметить что `value` преобразит значение как для страниц редактирования так и для страниц обзора.
Если препроцессинг нужен только для определённой страницы, используем `editor_value` для страницы редактирования и `pane_value` для страницы обзора:
input :created_at do
pane_value { item.created_at.strftime('%d %m, %Y') }
end
Зависимости
Rear свтоматически найдёт зависимости и создаст интерфейс для управления ими.
Единственное что нужно/можно изменить это исключить определённые зависимости или сделать их readonly.
Исключаем зависимости:
class Page < ActiveRecord::Base
belongs_to :author
include Rear
ignore_assoc :author
ignore_assoc :tags
# или
ignored_assocs :author, :tags
end
Отображаем зависимости в режиме только для чтения:
class Page < ActiveRecord::Base
include Rear
readonly_assoc :author
readonly_assoc :tags
# или
readonly_assocs :author, :tags
end
На этом пока всё.
Если хаброобщество проявит интерес, будет вторая часть, про фильтры и другие вкусности.
Автор: slivu