Как стать автором
Обновить

gem the_sortable_tree

Время на прочтение3 мин
Количество просмотров3.2K
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



На данный момент предусмотрено два варианта отрисовки:

  1. Сортируемое дерево (Административный интерфейс)
  2. Обычное дерево (Пользовательский интерфейс)


Примерно так выглядит дерево для пользователя



Установить гем и начать его использовать очень просто.

Дополните свой 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 < ApplicationController
  include TheSortableTreeController::ReversedRebuild

  def manage
    @pages = Page.reversed_nested_set.all
  end

end


Отрисуем дерево для администратора разместив во вьюшке код.


- content_for :css do
  = stylesheet_link_tag 'the_sortable_tree', :media => :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_tree

P.S.: Если вы заметили орфографическую или синтаксическую ошибку, ошибку в коде или любую другую ошибку, пожалуйста, сообщите мне в личку, я буду вам очень благодарен. Заранее спасибо!
Теги:
Хабы:
+23
Комментарии13

Публикации

Истории

Работа

Ruby on Rails
11 вакансий

Ближайшие события