Статьи

От новичка до ниндзя: как освоить использование плагинов в Rails

Ниже приведен небольшой отрывок из нашей книги Rails: Novice To Ninja , доступной для членов SitePoint Premium . Печатные копии продаются в магазинах по всему миру, или вы можете заказать их здесь . Мы надеемся, что вам понравится этот экстракт и вы найдете его полезным.

Плагины Rails

Хотя эта книга не может охватить все встроенные функциональные возможности, которые поставляются с Rails, и есть множество функциональных возможностей, которые вы можете открыть и поэкспериментировать после выхода из последней главы, архитектура плагинов Rails заслуживает нашего внимания.

Что такое плагин?

Плагин — это компонент, который вы можете добавить в свое приложение для расширения его функциональности. Хотя вы, конечно, можете написать свои собственные плагины, мы ограничимся нашим обсуждением здесь использованием существующих плагинов. Плагины были разработаны для различных частей инфраструктуры Rails, добавив такие функции, как:

  • расширения функциональности ActiveRecord
  • вспомогательные методы
  • новые механизмы шаблонов (для кодирования представления с использованием альтернативного языка шаблонов)

Количество существующих плагинов Rails огромно и растет с каждым днем. Программисты в сообществах Ruby и Rails отлично умеют делиться кодом и создавать полезные плагины на основе необходимых им расширений. Хороший ресурс существующих плагинов Rails можно найти, выполнив поиск «Rails» на сайте Rubygems или на сайте Ruby Toolbox .

Плагины распространяются в виде гемов, которые мы рассмотрели в главе 2. Плагины можно Gemfile в существующее приложение Rails, добавив их в Gemfile и запустив Gemfile bundle install . Вы, наверное, помните наше обсуждение Bundler из главы 4, где его работа заключается в управлении зависимостями приложений. Bundler упрощает включение существующих плагинов в наше приложение.

Поиск плагина, который делает то, что вам нужно, — это обычно просто поиск в Google или RubyGems. Как видно из рисунка 10-1, поиск «маркировки рельсов» вызывает несколько созданных драгоценных камней, включая один, называемый acts-as-taggable-on .

Рисунок 10-1. Поиск плагина на "маркировка рельсов"

Рисунок 10-1. Поиск плагина для «маркировки рельсов»

Подавляющее большинство драгоценных камней хранят свои источники на GitHub , в том числе acts-as-taggable-on с первой ссылки в нашем поиске выше. Переход по этой ссылке ведет к источнику на GitHub, как показано на рисунке 10-2.

10-2. GitHub-репозиторий для «Actions-As-Taggable-On»

10-2. GitHub-репозиторий для «Actions-As-Taggable-On»

В большинстве исходных репозиториев GitHub есть файл README или README.md котором объясняется, что делает гем, как его устанавливать и использовать и так далее. acts-as-taggable-on следует этому соглашению, которое можно увидеть на рисунке 10-3. Он объясняет объект драгоценного камня, поддерживаемые версии Rails, а также как установить и настроить драгоценный камень.

10-3. Стандартный файл README.

10-3. Стандартный файл README.

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

Нет времени для обзывания

Есть много способов расширить Rails; Например, используя «плагин», «двигатель» и «Railtie», чтобы назвать несколько. Несмотря на наличие технических различий между этими элементами, они часто (неправильно) используются взаимозаменяемо. Определение этих терминов и их различий выходит за рамки этой книги, поэтому сейчас я буду придерживаться слова «плагин». По мере развития вашего Rails-фу, вы, несомненно, захотите провести некоторое исследование расширяемости Rails. Бум — я только что превратил эту записку в ЭКСТРА КРЕДИТ!

Хорошо, достаточно теории! Давайте продолжим и установим наш первый плагин.

Добавление тегов в Readit

Маркировка — это процесс, с помощью которого создатели контента прикрепляют простые текстовые метки к своим данным, будь то фотография, ссылка или обзор ресторана. Эти теги сильно различаются по своей природе; например, они могут быть связаны с местоположением или содержанием. Это приводит к тому, что у каждого, кажется, есть уникальная система для пометки данных. В настоящее время хэштег (#), вероятно, является наиболее популярной формой пометки контента метаданными благодаря Twitter!

Тэги, безусловно, более гибкие, чем дерево категорий, поскольку они позволяют вам назначать любое количество тегов на любое количество данных. Разработанное соглашение заключается в том, что пользователь вводит теги для элемента контента в текстовое поле. Несколько тегов должны быть разделены пробелом или запятой.

Представляем Gem acts-as-taggable-on

Вместо того, чтобы изобретать велосипед и внедрять нашу собственную систему тегов для Readit, мы будем использовать один из доступных плагинов Rails для этой работы, вышеупомянутый acts-as-taggable-on . Вам может быть интересно, какое имя разработчик изначально выбрал для своего плагина. В какой-то момент сам Дэвид Хайнемайер Ханссон (David Heinemeier Hansson) на самом деле разработал плагин acts_as_taggable в качестве доказательства концепции некоторых новых функций Rails. Он не был предназначен для производственного использования и с тех пор устарел, но был снова поднят, потому что тегирование является таким важным компонентом современных веб-сайтов с пользовательским контентом.

Джонатан Виней, основной вкладчик Rails и всесторонний гуру, взялся за то, где остановился Хайнемайер Ханссон, и создал свою работу под названием acts_as_taggable_on_steroids . Тем не менее, разработка пошла на спад, поэтому другое имя разработчика, Майкл Блай, сформировало acts-as-taggable-on и с тех пор развивает его. С этим небольшим количеством истории семьи давайте посмотрим, что этот плагин может сделать для нас.

История acts_as_*

Поскольку это далеко от очевидного названия для плагина, позвольте мне объяснить acts_as_* соглашения об именах acts_as_* .

В собственном хранилище плагинов Rails можно найти ряд действий, которые являются функциональными расширениями модели ActiveRecord . Эти действия наделяют модели определенной функциональностью, которую обычно можно включить с помощью одной строки кода.

Поскольку эта функциональность позволяет моделям «действовать как что-то другое», возникла договоренность об именовании этих функциональных дополнений «акты», и вскоре последовал код, который обеспечивает функциональность acts_as_something .

На момент написания этой книги на Rubygems.org было доступно множество драгоценных камней «действует как»: acts_as_list , acts_as_tree и acts_as_paranoid , и многие другие. Хотя некоторые из них более сложны, чем другие, каждое из этих действий применяет иерархию к набору объектов модели. В случае acts_as_list объекты располагаются в плоском списке; В случае с acts_as_tree полученная иерархия представляет собой сложную древовидную систему, например, используемую в многопоточном форуме.

Но как насчет acts-as-taggable-on ? Как следует из названия, этот плагин предоставляет простой, но эффективный способ, с помощью которого вы можете сделать ваши модели тегируемыми. Он поставляется с собственным классом модели ActiveRecord называемым ActsAsTaggableOn::Tag , а также с возможностью разбора списка тегов, разделенных пробелами, на отдельные объекты модели класса ActsAsTaggableOn::Tag .

Меры безопасности пространства имен

Вы, вероятно, заметили, что класс Tag находится в пространстве имен в ActsAsTaggableOn . Классы пространств имен внутри гемов — это лучшая практика сообщества Ruby, основанная на годах, когда имена классов топали друг с другом из разных гемов и библиотек. Tag — это довольно распространенное имя, поэтому размещение его в пространстве имен ActsAsTaggableOn гарантирует, что мы избежим загрузки другого драгоценного камня, который захламляет класс.

Конечно, прежде чем мы сможем поиграть с этим плагином, нам нужно его установить.

Установка Gem acts-as-taggable-on

Чтобы установить гем, перейдите в корневую папку приложения и добавьте следующую строку в Gemfile :

 gem "acts-as-taggable-on", "~> 4.0" 

~> Сообщает Bundler, что нам нужна любая версия из серии 4.x. Если 4.2 — последняя версия, это то, что мы получим; однако, если бы выпали версии 4.2, то 5.0, мы бы все равно получили 4.2. Есть смысл?

Теперь запустите следующее:

 $ bundle install Fetching gem metadata from https://rubygems.org/........... Fetching version metadata from https://rubygems.org/... Fetching dependency metadata from https://rubygems.org/.. Resolving dependencies... Using rake 10.5.0 Using i18n 0.7.0 Using json 1.8.3 Using minitest 5.8.4 ... Installing acts-as-taggable-on 4.0.0.pre ... Bundle complete! 14 Gemfile dependencies, 56 gems now installed. Use `bundle show [gemname]` to see where a bundled gem is installed. Post-install message from acts-as-taggable-on: When upgrading 

Как вы можете видеть, Bundler проходит через все зависимости нашего приложения, в том числе устанавливает acts-as-taggable-on в «комплект» приложения. Есть даже пост-установочное сообщение от acts-as-taggable-on о том, что делать дальше.

Создание миграции для плагина

Наш план состоит в том, чтобы позволить пользователям нашего приложения добавлять теги в истории, представленные в Readit, поэтому наша модель Story должна быть помечена тегами. Как сами теги, так и отношения между тегами и историями должны где-то храниться, поэтому мы будем использовать миграцию для создания новых таблиц. И хотя этот плагин использует новую модель (модель ActsAsTaggableOn::Tag предоставляемую плагином acts-as-taggable-on ), модель не была создана командой rails generate , поэтому нам еще предстоит миграция, чтобы пойти с этим. К счастью, плагин поставляется с удобным методом генератора для создания подходящей миграции:

 $ rails acts_as_taggable_on_engine:install:migrations Running via Spring preloader in process 64781 Copied migration 201...7_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine Copied migration 201...8_add_missing_unique_indices.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine Copied migration 2_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine Copied migration 201...0_add_missing_taggable_index.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine Copied migration 201...1_change_collation_for_tag_names.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine Copied migration 201...2_add_missing_indexes.acts_as_taggable_on_engine.rb from acts_as_taggable_on_engine 

Rake’n’rails

В сообщении, полученном после того, как мы в комплекте, указано, что вы должны использовать rails вместо rails Добро пожаловать в кровоточащий край. В предыдущих версиях Rails rake использовался для выполнения подобных задач, но Rails 5 добавил rails в качестве псевдонима. Это должно было позволить разработчикам использовать rails для всех генераторов и задач.

Эта задача скопировала пять миграций в наш каталог db/migrate . Эти файлы производят таблицы, используемые acts-as-taggable-on , наряду с созданием некоторых индексов базы данных и других артефактов базы данных. Плагин acts-as-taggable-on использует две таблицы:

  • В таблице tags хранится модель ActsAsTaggableOn::Tag , которая является обычной моделью ActiveRecord . Эта таблица содержит одну запись для каждого тега. Так, например, если вы пометили две или более моделей Story тегом ruby , в базе данных будет храниться только один ActsAsTaggableOn::Tag ( ruby ). Такой подход позволяет пользователям нашего приложения легко находить контент; если пользователи заинтересованы в поиске историй о Ruby, они могут просматривать все истории, к которым был применен тег ruby .
  • В таблице taggings хранятся фактические сопоставления между ActsAsTaggableOn::Tag и теми моделями, которые используют функциональные возможности acts-as-taggable-on .

Ниже приведен код миграции, который был сгенерирован для нас. Он готов к использованию как есть и хранится в файле db/migrate/xxxx_acts_as_taggable_on_migration.rb :

 class ActsAsTaggableOnMigration < ActiveRecord::Migration def self.up create_table :tags do |t| t.string :name end create_table :taggings do |t| t.references :tag # You should make sure that the column created is # long enough to store the required class names. t.references :taggable, polymorphic: true t.references :tagger, polymorphic: true # Limit is created to prevent MySQL error on index # length for MyISAM table type: http://bit.ly/vgW2Ql t.string :context, limit: 128 t.datetime :created_at end add_index :taggings, :tag_id add_index :taggings, [:taggable_id, :taggable_type, :context] end def self.down drop_table :taggings drop_table :tags end end 

Эта миграция начинается достаточно просто. Он создает таблицу tags которая содержит только один столбец: name (в дополнение к столбцу id принадлежащему каждой таблице).

Хотя это может показаться простым на поверхности, таблица taggings немного сложнее, чем просто список объектов и их тегов. Как уже упоминалось, можно сделать более одной модели в вашем приложении тегируемой; однако сопоставления между ActsAsTaggableOn::Tag и теми моделями, к которым была добавлена ​​функция тегирования, используют одну таблицу.

acts-as-taggable-on использует каждый из столбцов, созданных в таблице taggings следующим образом:

  • tag_id создается t.references :tag и хранит id ActsAsTaggableOn::Tag
  • taggable_id создается с помощью t.references :taggable, polymorphic: true и хранит id объекта, который помечается (например, идентификатор Story )
  • taggable_type создается t.references :taggable, polymorphic: true и хранит класс t.references :taggable, polymorphic: true объекта (например, Story )
  • tagger_id создается t.references :tagger и хранит id пользователя, который создал тег (например, идентификатор User )
  • tagger_type создается t.references :tagger и хранит класс объекта, который выполняет тегирование (например, User )

Вы можете спросить, что означает «полиморфный» в нашей миграции. Держись, я скоро расскажу об этом.

Прежде, чем мы сможем дать нашей модели Story несколько acts-as-taggable-on , мы должны применить только что созданную миграцию, как показано ниже.

10-4. Применение сгенерированной миграции

10-4. Применение сгенерированной миграции

Большой! Теперь мы можем сделать нашу модель Story тегируемой. Давайте поговорим о полиморфных ассоциациях.

Чтобы прочитать полную книгу Гленна Гудрича «Rails: Novice To Ninja», купите ее здесь . У нас также есть предстоящая АМА с Гленном Гудричем, где он ответит на все ваши вопросы о Rails. Подпишитесь на это здесь .

EmailV2