Статьи

Создавайте красивые интерфейсы администрирования с Active Admin

Каждый веб-разработчик знает, что создание интерфейса администрирования для своих проектов — невероятно утомительная задача. К счастью, есть инструменты, которые значительно упрощают эту задачу. В этом руководстве я покажу вам, как использовать Active Admin , недавно запущенную инфраструктуру администрирования для приложений Ruby on Rails.

Вы можете использовать Active Admin, чтобы добавить интерфейс администрирования в текущий проект, или даже использовать его для создания законченного веб-приложения с нуля — быстро и легко.

Сегодня мы будем делать последнее, создавая довольно простую систему управления проектами. Это может показаться довольно большой работой, но Active Admin сделает большую часть работы за нас!


Я предполагаю, что у вас есть некоторые предыдущие знания Ruby on Rails, особенно связанные с проверкой моделей, так как Active Admin позаботится об остальном интерфейсе приложения. Кроме того, у вас должна быть уже настроена среда разработки для Ruby on Rails 3.1, включая Ruby 1.9.2.

Обратитесь к этой статье, если вам требуется помощь при установке Ruby и Rails.

Создайте приложение, над которым мы будем работать, выполнив следующую команду в вашем терминале:

1
rails new active_admin

Затем откройте ваш Gemfile и добавьте следующие строки:

1
2
gem ‘activeadmin’
gem ‘meta_search’, ‘>= 1.1.0.pre’

Последний драгоценный камень необходим Active Admin для работы с Rails 3.1, поэтому не забывайте об этом. После этого выполните команду bundle install для установки гемов. Теперь нам нужно завершить установку Active Admin, выполнив следующую команду:

1
rails generate active_admin:install

Это сгенерирует все необходимые инициализаторы и миграции для работы Active Admin. Он также создаст модель AdminUser для аутентификации, поэтому запустите rake db:migrate чтобы создать все необходимые таблицы базы данных. Кроме того, вам нужно добавить одну строку в ваш файл config/environments/development.rb , чтобы отправка писем работала:

1
config.action_mailer.default_url_options = { :host => ‘localhost:3000’ }

Как только это будет сделано, запустите rails server и укажите свой браузер на localhost: 3000 / admin . Вас встретит приятная форма входа. Просто введите «[email protected]» в качестве адреса электронной почты и «пароль» в качестве пароля и нажмите «Войти». Теперь вы должны увидеть хороший интерфейс администрирования.


Как вы можете видеть из только что созданной веб-страницы, вы пока ничего не можете сделать. Нам понадобится способ редактирования наших пользователей, и мы можем сделать это с помощью Active Admin. Каркас использует то, что называется «Ресурсы». Ресурсы сопоставляют модели с панелями администрирования. Вам нужно сгенерировать их с помощью команды в вашем терминале, чтобы Active Admin мог знать об их существовании, поэтому продолжайте:

1
rails generate active_admin:resource AdminUser

Синтаксис этой команды прост: просто напишите название модели базы данных в конце. Это создаст файл в папке app/admin именем admin_users.rb . Теперь, если вы обновите свой браузер, вы увидите новую ссылку в верхней панели, которая называется «Admin Users». Нажав, вы попадете на панель администратора Admin User. Теперь он, вероятно, будет выглядеть немного перегруженным, так как по умолчанию Active Admin показывает все столбцы модели, и, учитывая, что среда использует Devise для аутентификации, вы увидите кучу столбцов, которые на самом деле не нужны. Это подводит нас к первой части нашей настройки: индексной странице.

Admin User

Настроить ресурсы Active Admin довольно легко (и интересно, если вы спросите меня). Откройте app/admin/admin_users.rb в вашем любимом текстовом редакторе и сделайте так:

1
2
3
4
5
6
7
8
9
ActiveAdmin.register AdminUser do
  index do
    column :email
    column :current_sign_in_at
    column :last_sign_in_at
    column :sign_in_count
    default_actions
  end
end

Давайте рассмотрим код:

  • Первая строка создается Active Admin и, как говорится, регистрирует новый ресурс. Это создало ссылку меню на верхней панели и все действия по умолчанию, например, таблицу, которую вы только что видели.
  • index метод позволяет нам настроить индексное представление, которое является таблицей, которая показывает все строки.
  • Внутри блока, который вы передаете методу index , вы указываете, какие столбцы вы хотите отобразить в таблице, т.е. запись column :email будет иметь Active Admin показать этот столбец в представлении.
  • default_actions — это удобный метод, который создает последний столбец со ссылками на детали, редакцию и удаление строки.

Последний шаг для этого представления — настроить форму. Если щелкнуть ссылку «Новый пользователь-администратор» в правом верхнем углу, вы увидите, что форма также содержит все столбцы модели, что, очевидно, не очень полезно. Поскольку Active Admin использует Devise, нам нужно только ввести адрес электронной почты для создания пользователя, а об остальном должен позаботиться самоцвет аутентификации. Чтобы настроить формы, которые отображает Active Admin, есть метод, который называется (как вы уже догадались):

01
02
03
04
05
06
07
08
09
10
11
12
ActiveAdmin.register AdminUser do
  index do
    # …
  end
 
  form do |f|
    f.inputs «Admin Details» do
      f.input :email
    end
    f.buttons
  end
end

Если код кажется вам знакомым, вы, возможно, уже использовали гем Formtastic . Давайте посмотрим на код:

  • Вы определяете представление формы, вызывая метод form и передавая ему блок с аргументом (в данном случае f ).
  • f.inputs создает набор полей. Совет: вам нужно добавить хотя бы один набор полей. Поля за пределами одного просто не будут отображаться в представлении.
  • Чтобы создать поле, просто вызовите f.input и передайте символ с именем столбца модели, в данном случае «email».
  • f.buttons создает f.buttons «Отправить» и «Отмена».

Вы можете дополнительно настроить формы, используя DSL (Domain Specific Language), предоставляемый Formtastic, так что взгляните на учебные пособия об этом драгоценном камне.

Последний шаг для работы этой формы: поскольку мы не предоставляем пароль, Devise не собирается позволять нам создавать запись, поэтому нам нужно добавить некоторый код в модель AdminUser :

1
2
3
4
5
after_create { |admin|
 
def password_required?
  new_record?
end

after_create вызов after_create гарантирует, что Devise отправит пользователю ссылку для создания нового пароля, а password_required? Метод позволит нам создать пользователя без предоставления пароля.

Иди попробуй. Создайте пользователя, а затем проверьте свою электронную почту на наличие ссылки, которая позволит вам создать новый пароль, и войдите в систему.


Мы собираемся создать простую систему управления проектами. Хотя это не что-то слишком сложное, просто то, что позволит нам управлять проектами и задачами для проекта и назначать задачи определенным пользователям. Прежде всего, это создать модель проекта:

1
rails generate model Project title:string

Active Admin использует модели Rails для проверки, и нам не нужны проекты без заголовка, поэтому давайте добавим некоторые проверки в сгенерированную модель:

1
2
# rails
validates :title, :presence => true

Теперь нам нужно сгенерировать ресурс Active Admin, запустив:

1
rails generate active_admin:resource Project

Пока это все, что нам нужно для проектов. После миграции базы данных взгляните на интерфейс, который вы только что создали. Создание проекта без заголовка не удается, чего мы и ожидали. Видите, чего вы достигли всего несколькими строками кода?


Проекты не очень полезны без задач, верно? Давайте добавим, что:

1
rails generate model Task project_id:integer admin_user_id:integer title:string is_done:boolean due_date:date

Это создает модель задачи, которую мы можем связать с проектами и пользователями. Идея состоит в том, что задача кому-то назначена и принадлежит проекту. Нам нужно установить эти отношения и проверки в модели:

1
2
3
4
5
6
7
class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :admin_user
 
  validates :title, :project_id, :admin_user_id, :presence => true
  validates :is_done, :inclusion => { :in => [true, false] }
end

Не забудьте также добавить отношения в модели Project и AdminUser:

1
2
3
4
5
class AdminUser < ActiveRecord::Base
  has_many :tasks
 
  # …
end
1
2
3
4
5
class Project < ActiveRecord::Base
  has_many :tasks
 
  # …
end

Выполните миграцию базы данных и зарегистрируйте модель задачи в Active Admin:

1
rails generate active_admin:resource Task

Теперь перейдите и посмотрите на панель задач в вашем браузере. Вы только что создали систему управления проектами! Молодец.


Система, которую мы только что создали, не слишком сложна. К счастью, Active Admin — это не просто создание хорошей системы строительных лесов, она дает вам гораздо больше возможностей, чем эта. Начнем с раздела «Проекты». Нам действительно не нужны id , created и updated столбцы, и, конечно, нам не нужно искать по этим столбцам. Давайте сделаем это так:

01
02
03
04
05
06
07
08
09
10
index do
  column :title do |project|
    link_to project.title, admin_project_path(project)
  end
 
  default_actions
end
 
# Filter only by title
filter :title

Несколько заметок здесь:

  • Когда вы указываете столбцы, вы можете настроить то, что напечатано в каждой строке. Просто передайте блок с аргументом и верните туда все, что вы хотите. В этом случае мы печатаем ссылку на страницу сведений о проекте, что проще, чем щелкнуть ссылку «Просмотр» справа.
  • Фильтры справа также можно настраивать. Просто добавьте вызов для filter для каждого столбца, который вы хотите фильтровать.

Страница с подробностями проекта немного скучна, не правда ли? Нам не нужны столбцы date и id здесь, и мы могли бы показать список задач более прямо. Настройка страницы сведений выполняется с помощью метода show в файле app/admin/projects.rb :

01
02
03
04
05
06
07
08
09
10
show :title => :title do
  panel «Tasks» do
    table_for project.tasks do |t|
      t.column(«Status») { |task|
      t.column(«Title») { |task|
      t.column(«Assigned To») { |task|
      t.column(«Due Date») { |task|
    end
  end
end

Давайте пройдемся по коду:

  • show :title => :title указывает заголовок страницы. Второе :title определяет столбец модели, который будет использоваться.
  • Вызывая panel "Tasks" мы создаем панель с заданным названием. В нем мы создаем пользовательскую таблицу для задач проекта, используя table_for .
  • Затем мы указываем каждый столбец и содержание, которое он должен иметь для каждой строки.
    • Столбец «Статус» будет содержать «Готово» или «Ожидание» независимо от того, выполнена задача или нет. status_tag — это метод, который отображает слово, переданное в очень хорошем стиле, и вы можете определить цвет, передавая второй аргумент : ok :warning и :error для цветов green, orange и red соответственно.
    • Столбец «Заголовок» будет содержать ссылку на задачу, чтобы мы могли ее редактировать.
    • В столбце «Назначено» просто содержится электронное письмо ответственного лица.
    • «Срок выполнения» будет содержать дату, когда задание должно быть выполнено, или просто «-», если дата не установлена.

Как насчет простого способа фильтрации задач, которые должны быть на этой неделе? Или задачи, которые опаздывают? Это легко! Просто используйте прицел. В файле tasks.rb добавьте это:

01
02
03
04
05
06
07
08
09
10
scope :all, :default => true
scope :due_this_week do |tasks|
  tasks.where(‘due_date > ? and due_date < ?’, Time.now, 1.week.from_now)
end
scope :late do |tasks|
  tasks.where(‘due_date < ?’, Time.now)
end
scope :mine do |tasks|
  tasks.where(:admin_user_id => current_admin_user.id)
end

Давайте рассмотрим этот код:

  • scope :all определяет область по умолчанию, показывая все строки.
  • scope принимает символ для имени, и вы можете передать блок с аргументом. Внутри блока вы можете уточнить поиск в соответствии с тем, что вам нужно. Вы также можете определить область действия внутри модели и просто назвать ее так же, как в этом файле.
  • Как видите, вы можете получить доступ к объекту текущего вошедшего в систему пользователя, используя current_admin_user .
Tasks2

Проверьте это! Прямо над таблицей вы увидите несколько ссылок, которые быстро покажут, сколько задач существует в каждой области, и позволяют быстро отфильтровать список. Вам следует дополнительно настроить таблицу и поисковые фильтры, но я оставлю эту задачу вам.

Теперь мы немного подправим детальный вид задачи, так как он выглядит довольно загроможденным:

01
02
03
04
05
06
07
08
09
10
11
12
13
show do
  panel «Task Details» do
    attributes_table_for task do
      row(«Status») { status_tag (task.is_done ? «Done» : «Pending»), (task.is_done ? :ok : :error) }
      row(«Title») { task.title }
      row(«Project») { link_to task.project.title, admin_project_path(task.project) }
      row(«Assigned To») { link_to task.admin_user.email, admin_admin_user_path(task.admin_user) }
      row(«Due Date») { task.due_date?
    end
  end
 
  active_admin_comments
end

Это покажет таблицу для атрибутов модели (отсюда и название метода attributes_table_for ). Вы задаете модель, в данном случае task , и в переданном блоке вы определяете строки, которые хотите показать. Это примерно то же самое, что мы определили для подробной страницы проекта, только для задачи. Вы можете спросить себя: для чего нужен метод «active_admin_comments»? Что ж, Active Admin предоставляет простую систему комментирования для каждой модели. Я включил это здесь, потому что комментирование задачи может быть очень полезным для обсуждения функциональности или чего-то подобного. Если вы не вызовете этот метод, комментарии будут скрыты.

Tasks

Есть еще одна вещь, которую я хотел бы показать при просмотре деталей задачи, и это остальные задачи уполномоченного для этого проекта. Это легко сделать с помощью боковых панелей!

1
2
3
4
5
6
sidebar «Other Tasks For This User», :only => :show do
  table_for current_admin_user.tasks.where(:project_id => task.project) do |t|
    t.column(«Status») { |task|
    t.column(«Title») { |task|
  end
end

Это создает панель боковой панели под названием «Другие задачи для этого пользователя», которая отображается только на странице «Показать». Он покажет таблицу для текущего пользователя- администратора и все задачи, в которых проект совпадает с показанным проектом (вы видите, task здесь будет ссылаться на отображаемую задачу, так как это страница сведений для одной задачи). Остальное примерно так же, как и раньше: некоторые столбцы с деталями задачи.


Возможно, вы заметили, когда вы впервые запустили браузер и вошли в свое приложение, что там был раздел «Панель инструментов». Это полностью настраиваемая страница, на которой вы можете показать практически все: таблицы, статистику и все, что угодно. Мы просто добавим список задач пользователя в качестве примера. Откройте файл dashboards.rb и измените его следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
ActiveAdmin::Dashboards.build do
  section «Your tasks for this week» do
    table_for current_admin_user.tasks.where(‘due_date > ? and due_date < ?’, Time.now, 1.week.from_now) do |t|
      t.column(«Status») { |task|
      t.column(«Title») { |task|
      t.column(«Assigned To») { |task|
      t.column(«Due Date») { |task|
    end
  end
 
  section «Tasks that are late» do
    table_for current_admin_user.tasks.where(‘due_date < ?’, Time.now) do |t|
      t.column(«Status») { |task|
      t.column(«Title») { |task|
      t.column(«Assigned To») { |task|
      t.column(«Due Date») { |task|
    end
  end
end

Код должен быть вам достаточно знаком. По сути, он создает два раздела (используя метод section и заголовок), по одной таблице каждый, в которой отображаются текущие и поздние задачи соответственно.

Dashboard

Мы создали обширное приложение всего за несколько шагов. Возможно, вы удивитесь, узнав, что Active Admin предлагает гораздо больше возможностей, но, конечно же, невозможно охватить их все в одном учебном пособии. Если вы хотите узнать больше об этом драгоценном камне, посетите activeadmin.info .

Вы также можете проверить мой проект, называемый active_invoices на GitHub, который представляет собой полноценное приложение для выставления счетов, созданное полностью с помощью Active Admin. Если у вас есть какие-либо вопросы, не стесняйтесь задавать их в комментариях или отправьте мне твит .