Що таке Rails-двигуни? Як створювати та інтегрувати їх?

Rails engines (двигуни Rails) це, по суті, мініатюрні додатки на Rails, які можна підключити до більшого додатку Rails. Вони дозволяють інкапсулювати конкретну функціональність, роблячи її повторно використовуваною та модульною. Двигуни особливо корисні, коли потрібно розробляти функції, які можуть бути спільними для кількох додатків Rails, такі як автентифікація, обробка платежів або будь-яка специфічна логіка для певної галузі.

Основні особливості двигунів Rails:

  1. Самодостатні: Вони мають власні компоненти MVC, маршрути, міграції та активи.
  2. Можна підключити: Ви можете підключити двигун до хост-додатку за допомогою методу mount у файлі routes.rb.
  3. Повторно використовувані: Після розробки їх можна упаковувати в gems та використовувати в інших проектах.
  4. Налаштовувані: Хост-додатки можуть переоприділяти або розширювати функціональність, яку надає двигун.

Типи двигунів Rails:

  1. Повний двигун: Включає власну структуру додатку, таку як контролери, моделі, вьюшки, хелпери та маршрути.
    2.
    Dummy Engine (Тестовий двигун): Використовується як тестовий або розробницький додаток для двигуна. Зазвичай розташовується в папці test/dummy або spec/dummy.

Ось детальне пояснення про двигуни Rails, разом з кодом для створення та інтеграції двигуна Rails:

Створення двигуна Rails

Для створення двигуна Rails використовуйте команду rails plugin new з прапорцем
--mountable.

Кроки:

  1. Створіть двигун:
rails plugin new my_engine --mountable

Ця команда створить директорію з назвою my_engine з такою ж структурою, як у додатку Rails, але обмежену лише двигуном.

2. Визначте специфічну для двигуна функціональність:

  • Відкрийте файл lib/my_engine/engine.rb:
module MyEngine  
 class Engine < ::Rails::Engine  
 isolate_namespace MyEngine  
 end  
end
  • Метод isolate_namespace забезпечує, щоб маршрути, контролери та хелпери двигуна не перетиналися з основним додатком.

**3.
Додати моделі, контролери та маршрути:

  • Додайте приклад моделі:
# app/models/my_engine/post.rb  
module MyEngine  
 class Post < ApplicationRecord  
 end  
end
  • Створіть контролер:
# app/controllers/my_engine/posts_controller.rb  
module MyEngine  
 class PostsController < ApplicationController  
 def index  
 @posts = Post.all  
 end  
 end  
end
  • Визначте маршрути:
# config/routes.rb  
MyEngine::Engine.routes.draw do  
 resources :posts  
end

4. Підготовка тестового додатку: Тестовий додаток Rails створюється в test/dummy або spec/dummy для тестування двигуна.

5. Упакуйте двигун: Упакуйте двигун як гем і додайте його в інші проекти.

Інтеграція двигуна Rails

Щоб інтегрувати двигун, потрібно змонтувати його в хостовому додатку Rails.

Кроки:

1.
Додати двигун до хост-додатку: Додайте двигун до файлу Gemfile:

gem 'my_engine', path: '../my_engine' #Локальний шлях

Або використовуйте віддалене джерело:

gem 'my_engine', git: 'https://github.com/username/my_engine.git'

2. Встановлення через Bundle: Виконайте команду bundle install, щоб завантажити двигун.

3. Монтуючи двигун: Змонтуйте двигун у файлі routes.rb:

Rails.application.routes.draw do  
 mount MyEngine::Engine, at: "/my_engine"  
end

4. Доступ до двигуна: Після монтування маршрути двигуна будуть доступні за вказаним шляхом (/my_engine в цьому випадку). Наприклад, перехід за адресою /my_engine/posts призведе до виклику PostsController з двигуна.

Тестування інтеграції

Після монтування двигуна переконайтесь, що він працює, звернувшись до його маршрутів через браузер або запустивши тестовий набір, що йде разом із двигуном.

Давайте поглиблено розглянемо упаковку Rails двигуна в гем та розширення його функціональності в хостовому додатку.

1.

Упаковка Rails двигуна в гем

Rails двигун можна розповсюджувати як гем, що робить його зручним для повторного використання в різних додатках.

Кроки для упаковки двигуна в гем

  1. Переконайтесь, що gemspec правильний. Файл gemspec автоматично генерується під час створення двигуна. Відкрийте my_engine.gemspec і оновіть його метадані:
Gem::Specification.new do |s|  
 s.name = "my_engine"  
 s.version = "0.1.0"  
 s.summary = "Приклад Rails двигуна"  
 s.description = "Надає повторно використовувану функціональність для управління постами"  
 s.authors = ["Ваше Ім'я"]  
 s.email = ["[email protected]"]  
 s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]  
 s.homepage = "https://github.com/your_username/my_engine"  
 s.license = "MIT"  
end

2. Додайте залежності (якщо є). Якщо ваш двигун залежить від певних гемів, оголосіть їх у файлі gemspec:

s.add_dependency "rails", "~> 7.0"  
s.add_dependency "devise", "~> 4.8"

3.
**Створення гема
. З кореневої директорії двигуна побудуйте гем:

gem build my_engine.gemspec

Це створить файл .gem (наприклад, my_engine-0.1.0.gem).

4. Відправка гема в репозиторій. Ви можете опублікувати ваш гем у репозиторії, наприклад, на RubyGems або на приватному сервері гемів.

  • Щоб відправити в RubyGems:
gem push my_engine-0.1.0.gem

Якщо гем є приватним, можна використовувати сервіс, наприклад, Gemfury або розгорнути приватний сервер гемів.

5. Встановлення гема в інші проекти. У вашому Gemfile додайте гем:

gem 'my_engine', '~> 0.1.0'

Запустіть bundle install, щоб його встановити.

2. Розширення функціональності двигуна

Ви можете налаштувати або перекрити частини двигуна в основному додатку.

Методи для розширення двигуна

A. Перекриття виглядів

Скопіюйте вигляди двигуна в основний додаток, щоб налаштувати їх:

  1. Знайдіть вигляди двигуна (наприклад, my_engine/app/views/my_engine/posts/index.html.erb).
    2.
    Скопіюйте їх у відповідну директорію основного додатку:
app/views/my_engine/posts/index.html.erb
  1. Змініть вигляди за необхідності.

B. Перекриття контролерів

Використовуйте class_eval Rails або успадкуйте від контролерів двигуна:

  1. Створіть новий контролер в основному додатку:
class MyEngine::PostsController < ApplicationController  
 def index  
 @posts = MyEngine::Post.published  
 end  
end
  1. Переконайтесь, що маршрути вказують на перекритий контролер.

C. Додавання власних маршрутів

Розширте маршрути двигуна в основному додатку:

  1. Використовуйте метод draw у файлі config/routes.rb:
Rails.application.routes.draw do  
 mount MyEngine::Engine, at: "/my_engine"  
 MyEngine::Engine.routes.draw do  
 get 'custom_route', to: 'posts#custom_action'  
 end  
end

D. Перекриття моделей

Розширте або налаштуйте моделі за допомогою Ruby’s prepend або class_eval:

1.
У основному додатку додайте декоратор (наприклад, app/models/my_engine/post_decorator.rb):

MyEngine::Post.class_eval do  
 scope :published, -> { where(published: true) }  
end

E. Додавання ініціалізаторів

Додайте власну конфігурацію для двигуна в директорії config/initializers/ основного додатку:

# config/initializers/my_engine.rb  
MyEngine.configure do |config|  
 config.some_setting = "custom_value"  
end

Кращі практики

  1. Зберігайте модульність двигуна: Інкапсулюйте логіку в межах двигуна, щоб зменшити залежність від основного додатку.
  2. Документуйте варіанти налаштування: Надайте чіткі інструкції для перекриття виглядів, контролерів і конфігурацій.
  3. Використовуйте версії: Дотримуйтеся семантичного версіонування для комунікації змін з користувачами гему.
  4. Уникайте жорстко закодованих URL: Використовуйте іменовані маршрути або параметри конфігурації, щоб зробити двигун гнучким.

Перекладено з: What are Rails engines? How to creating and integrating one?

Leave a Reply

Your email address will not be published. Required fields are marked *