Ruby on Rails / gem the_sortable_tree

в 7:31, , рубрики: nested set, ruby, метки: ,

Ruby on Rails / gem the_sortable_tree
TheSortableTree — гем, реализующий функционал Drag&Drop для деревьев построенных на основе гемов awesome_nested_set или nested_set.
В 2008 году, когда мы делали свою первую социалку на рельсах, я впервые столкнулся гемом better_nested_set. Гем был прекрасен (я имею ввиду по сути, не по коду, реализация тогда еще хромала) и, пожалуй, одного только его было достаточно, что бы убедить меня забыть программирование на PHP, как страшный сон.
Мы использовали гем для формирования многоуровневого дерева комментариев. Но было одно но… В тот момент не было ни одного хелпера, который бы позволял отрисовывать эти деревья. Из-за этого приходилось выдумывать свои велосипеды. Свой велосипед сделал и я.
Нет, я не склонен драматизировать и усложнять процесс реализации. У каждого из нас свои предпочтения. Поэтому я сделал самую обычную рекурсию, которая отрисовывает дерево с помощью паршелов.
Да, меня критиковали — это медленно отрисовывается, это не сработает на дереве из 10 000 элементов, надо по-другому и вообще…
Однако с 2008 года я так и не увидел чего-то другого, более доступного, быстрого и простого. Возможно, я плохо искал.
И вот я, потупив взор и нервно теребя в руках носовой платочек, представляю вам реинкарнацию моего хелпера в виде гема основанного на Rails Engines.
Уверен, для отрисовки небольших деревьев (до 100 элементов) и создания небольших CMS, где хочется управлять деревом простым перетаскиванием, мой хелпер подойдет идеально.https://github.com/the-teacher/the_sortable_tree
На данный момент предусмотрено два варианта отрисовки:Сортируемое дерево (Административный интерфейс)

Обычное дерево (Пользовательский интерфейс)

Примерно так выглядит дерево для пользователя
Установить гем и начать его использовать очень просто.
Дополните свой Gemfile. Нам потребуется HAML, Awesome nested set и сам хелпер отрисовки the_sortable_tree.
gem 'haml'
gem 'awesome_nested_set' # gem 'nested_set'
gem 'the_sortable_tree'

Я специально убрал жесткую зависимость от HAML, чтобы фанаты ERB или SLIM смогли тоже использовать хелпер, но вам ребята придется самостоятельно переконвертировать вьюшки из хамла.
Проверим, что все JS библиотеки подключеныapp/assets/javascripts/application.js
//= require jquery
//= require jquery-ui
//= require jquery_ujs

Рассмотрим использование гема на примере модели Page.
Добавим в модель скопы
class Page < ActiveRecord::Base
acts_as_nested_set
include TheSortableTree::Scopes
end

В контроллер добавим функцию перестроения дерева
class PagesController < ApplicationController
include TheSortableTreeController::Rebuild
end

Если вы используете обратное дерево (иногда требуется перевернутое дерево, например для формирования списка новостей), то используйте другой инклуд.
class PagesController < ApplicationController
include TheSortableTreeController::ReversedRebuild
end

Дополните роуты.
Один action нам потребуется, чтобы отобразить дерево. Как вы его назовете — не важно. У меня это :manage.rebuild — метод перемещающий элемент дерева из одной позиции в другую. Этот метод зашит в гем — он обязателен.
resources :pages do
collection do
get :manage
post :rebuild
end
end

Завершим код контроллера.
Получим все дерево (прямой порядок выборки)
class PagesController < ApplicationController
include TheSortableTreeController::Rebuild

def manage
@pages = Page.nested_set.all
end
end

Обратный порядок выборки
class PagesController :screen
- content_for :js do
= javascript_include_tag 'jquery.ui.nestedSortable'

= sortable_tree @pages, :new_url => new_page_path, :max_levels => 4

Или отрисуем дерево для пользователя.
- content_for :css do
= stylesheet_link_tag 'the_sortable_tree_min', :media => :screen

= sortable_tree @pages, :new_url => new_page_path, :path => 'the_sortable_tree_min'

Для того, чтобы content_for :css и content_for :js сработали, добавьте в layouts/application.xxx yield(:js) и yield(:css).
Конечно, то, как вы будите подключать js и css — это ваше дело.
Всё! Дерево должно отображаться и перетаскиваться.
Если что-то не получается — скачайте и запустите LiveDemo.
Кастомизация отображения

Запустите генератор вьюшек и укажите ему название контроллера.
rails g the_sortable_tree:views pages

Для кастомизации пользовательского дерева укажите параметр min
rails g the_sortable_tree:views pages min

Отредактируйте вьюшки и укажите хелперу, где они находятся:
= sortable_tree @pages, :new_url => new_page_path, :path => 'pages/the_sortable_tree'

Я предполагаю, что разные модели могут по-разному отрисовываться — поэтому вьюшки копируются в папку вьюшек указанного контроллера.
Надеюсь, это кому-то пригодится.https://github.com/the-teacher/the_sortable_treeP.S.: Если вы заметили орфографическую или синтаксическую ошибку, ошибку в коде или любую другую ошибку, пожалуйста, сообщите мне в личку, я буду вам очень благодарен. Заранее спасибо!


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js