socialgekon.com
  • Основен
  • Процес На Проектиране
  • Хора И Екипи
  • Дизайнерски Живот
  • Други
Back-End

Ръководство за релсови двигатели в дивата природа: Примери за реални двигатели в действие

Защо Rails двигателите не се използват по-често? Не знам отговора, но мисля, че обобщението на „Всичко е двигател“ е скрило проблемните домейни, които те могат да помогнат за решаването.

Превъзходното Документация на Rails Guide за започване на работа с Rails Engines се посочват четири популярни примера за внедряване на Rails Engine: Forem, Devise, Spree и RefineryCMS. Това са фантастични случаи на използване на двигатели в реалния свят, всеки от които използва различен подход за интегриране с приложението Rails.

Всяко ръководство на Rails трябва да обхваща темата за моделите за проектиране на двигатели на Rails и техните примери.



Разглеждането на части от това как тези скъпоценни камъни са конфигурирани и съставени ще даде напреднали Разработчиците на Ruby on Rails ценни знания за това какви модели или техники се изпробват и тестват в дивата природа, така че когато дойде времето, можете да имате няколко допълнителни опции за оценка.

Очаквам да се запознаете бегло с начина, по който работи един двигател, така че ако смятате, че нещо не се събира, моля, прегледайте най-отличното Ръководство за Rails Първи стъпки с двигатели .

Без повече шум, нека се впуснем в дивия свят на примери за Rails двигатели!

Отивам

Двигател за Rails, който се стреми да бъде най-добрата малка форумна система някога

Този скъпоценен камък следва посоката на Ръководството за релси за двигатели към писмото. Това е огромен пример и разглеждането на неговото хранилище ще ви даде представа колко далеч можете да разтегнете основната настройка.

Това е скъпоценен камък с един двигател, който използва няколко техники за интегриране с основното приложение.

module ::Forem class Engine

Интересното тук е Decorators.register! клас метод, изложен от скъпоценния камък на Decorators. Той капсулира файлове за зареждане, които не биха били включени в процеса на автоматично зареждане на Rails. Може би си спомняте, че използването на явни require инструкции руши автоматично презареждане в режим на разработка, така че това е спасител! Ще бъде по-ясно да използваме примера от Ръководството, за да илюстрираме какво се случва:

config.to_prepare do Dir.glob(Rails.root + 'app/decorators/**/*_decorator*.rb').each do |c| require_dependency(c) end end

Повечето магии за конфигурацията на Forem се случват в горната дефиниция на основния модул на Forem Този файл разчита на user_class променлива, зададена във файл на инициализатор:

Forem.user_class = 'User'

Постигате това с помощта на mattr_accessor но всичко е в Ръководството за релси, така че няма да повтарям това тук. С това на място Forem украсява потребителския клас с всичко необходимо за стартиране на приложението му:

module Forem class <'Forem::Post', :foreign_key => 'user_id' # ... def forem_moderate_posts? Forem.moderate_first_post && !forem_approved_to_post? end alias_method :forem_needs_moderation?, :forem_moderate_posts? # ...

Което се оказва доста! Изрязах мнозинството, но оставих в дефиниция на асоциация, както и метод на екземпляр, за да ви покажа типа редове, които можете да намерите там.

Погледът на целия файл може да ви покаже колко управляемо е пренасянето на част от вашето приложение за повторна употреба към Engine.

Украсяването е името на играта в използването на двигателя по подразбиране. Като краен потребител на скъпоценния камък можете да замените модел, изглед и контролери, като създадете свои собствени версии на класовете, използвайки конвенциите за път на файла и имената на файлове, изложени в декораторния скъпоценен камък README. С този подход обаче има разходи, особено когато двигателят получи значително надстройване на версията - поддържането на поддържането на вашите декорации може бързо да излезе извън контрол. Тук не цитирам Forem, вярвам, че те са непоклатими в спазването на стегнатата основна функционалност, но имайте това предвид, ако създадете двигател и решите да преминете към основен ремонт.

Нека да обобщим това: това е шаблонът за проектиране на Rails по подразбиране, разчитащ на крайни потребители, декориращи изгледи, контролери и модели, заедно с конфигуриране на основни настройки чрез инициализиращи файлове. Това работи добре за много фокусирана и свързана функционалност.

Девиз

Гъвкаво решение за удостоверяване на Rails

Ще откриете, че Engine е много подобен на приложението Rails, с views, controllers и models директории. Devise е добър пример за капсулиране на приложение и излагане на удобна точка за интеграция. Нека да разгледаме как точно работи това.

Ще разпознаете тези редове код, ако сте разработчик на Rails повече от няколко седмици:

class User

Всеки параметър, предаден на devise метод представлява модул в Devise Engine. Има общо десет от тези модули, които наследяват от познатото ActiveSupport::Concern. Те удължават User клас чрез извикване на devise метод в обхвата му.

Наличието на този тип точка на интеграция е много гъвкаво, можете да добавите или премахнете някой от тези параметри, за да промените нивото на функционалност, което изисква двигателят да изпълнява. Това също означава, че не е необходимо да кодирате твърдо кой модел бихте искали да използвате в рамките на инициализационен файл, както е предложено от Ръководството на Rails за двигатели. С други думи, това не е необходимо:

Devise.user_model = 'User'

Тази абстракция също означава, че можете да приложите това към повече от един потребителски модел в рамките на едно и също приложение (admin и user например), докато подходът на конфигурационния файл ще ви остави обвързан с един модел с удостоверяване. Това не е най-големият момент за продажба, но илюстрира различен начин за решаване на проблем.

Devise се простира ActiveRecord::Base със собствен модул, който включва devise дефиниция на метод:

# lib/devise/orm/active_record.rb ActiveRecord::Base.extend Devise::Models

Всеки клас, наследяващ от ActiveRecord::Base сега ще има достъп до методите на класа, дефинирани в Devise::Models:

#lib/devise/models.rb module Devise module Models # ... def devise(*modules) selected_modules = modules.map(&:to_sym).uniq # ... selected_modules.each do |m| mod = Devise::Models.const_get(m.to_s.classify) if mod.const_defined?('ClassMethods') class_mod = mod.const_get('ClassMethods') extend class_mod # ... end include mod end end # ... end end

(Премахнах много код (# ...), за да подчертая важните части.)

Перифразирайки кода, за всяко име на модул, предадено на devise метод, който сме:

  • зареждане на модула, който посочихме, който живее под Devise::Models (Devise::Models.const_get(m.to_s.classify)
  • разширяване на User клас с ClassMethods модул, ако има такъв
  • включва посочения модул (include mod), за да добави методите на неговия екземпляр към класа, извикващ devise метод (User)

Ако искате да създадете модул, който може да бъде зареден по този начин, ще трябва да се уверите, че той следва обичайното ActiveSupport::Concern интерфейс, но го поставете под Devise:Models тъй като тук търсим да извлечем константата:

module Devise module Models module Authenticatable extend ActiveSupport::Concern included do # ... end module ClassMethods # ... end end end end

Фу.

Ако сте използвали Rails ’Concerns преди и сте изпитали повторната използваемост, която те си позволяват, тогава можете да оцените хубавостите на този подход. Накратко, разбиването на функционалността по този начин улеснява тестването, като се абстрахира от ActiveRecord модел и има по-ниски режийни разходи от шаблона по подразбиране, използван от Forem, когато става въпрос за разширяване на функционалността.

Този модел се състои от разбиване на вашата функционалност към Rails Concerns и излагане на конфигурационна точка, която да ги включва или изключва в рамките на даден обхват. Двигател, формиран по този начин, е удобен за крайния потребител - фактор, допринасящ за успеха и популярността на Devise. А сега знаете и как да го направите!

Spree

Пълно решение за електронна търговия с отворен код за Ruby on Rails

Spree премина през колосални усилия да постави монолитното си приложение под контрол с преминаване към използване на двигатели. Архитектурният дизайн, с който сега се търкалят, е скъпоценен камък „Spree“, който съдържа много скъпоценни камъни на Engine.

Тези Двигатели създават дялове в поведение, което може да сте свикнали да виждате в рамките на монолитно приложение или да се разпространява между приложения:

  • spree_api (RESTful API)
  • spree_frontend (ориентирани към потребителя компоненти)
  • spree_backend (Администраторска област)
  • spree_cmd (инструменти за командния ред)
  • spree_core (Модели и пощенски програми, основните компоненти на Spree, без които не може да работи)
  • spree_sample (примерни данни)

Обхващащият скъпоценен камък ги свързва, оставяйки на разработчика избор в нивото на функционалност, която да изисква. Например, можете да стартирате само с spree_core Двигател и обвийте своя собствен интерфейс около него.

Основният скъпоценен камък Spree изисква тези двигатели:

# lib/spree.rb require 'spree_core' require 'spree_api' require 'spree_backend' require 'spree_frontend'

След това всеки двигател трябва да персонализира своя engine_name и root път (последният обикновено сочи към скъпоценния камък от най-високо ниво) и да се конфигурират, като се закачат в процеса на инициализация:

# api/lib/spree/api/engine.rb require 'rails/engine' module Spree module Api class Engine :load_config_initializers do |app| app.config.spree = Spree::Core::Environment.new end # ... end end end

Може или не може да разпознаете този метод на инициализатор: той е част от Railtie и е кука, която ви дава възможност да добавяте или премахвате стъпки от инициализацията на рамката Rails. Spree разчита силно на тази кука, за да конфигурира сложната си среда за всички свои двигатели.

Използвайки горния пример по време на изпълнение, ще имате достъп до настройките си чрез достъп до най-горното ниво Rails константа:

Rails.application.config.spree

С това ръководство за дизайн на Rails двигател по-горе бихме могли да го наречем ден, но Spree има много невероятен код, така че нека да се потопим в това как те използват инициализацията, за да споделят конфигурация между Двигатели и основното приложение Rails.

Spree има сложна система за предпочитания, която зарежда, като добавя стъпка в процеса на инициализация:

# api/lib/spree/api/engine.rb initializer 'spree.environment', :before => :load_config_initializers do |app| app.config.spree = Spree::Core::Environment.new end

Тук се прикачваме към app.config.spree нов Spree::Core::Environment инстанция. В рамките на приложението rails ще имате достъп до това чрез Rails.application.config.spree отвсякъде - модели, контролери, изгледи.

Придвижвайки се надолу, Spree::Core::Environment клас, който създаваме изглежда така:

module Spree module Core class Environment attr_accessor :preferences def initialize @preferences = Spree::AppConfiguration.new end end end end

Той излага a :preferences променлива, зададена за нов екземпляр на Spree::AppConfiguration клас, който от своя страна използва preference метод, дефиниран в Preferences::Configuration клас за задаване на опции с настройки по подразбиране за общата конфигурация на приложението:

module Spree class AppConfiguration

Няма да показвам Preferences::Configuration файл, защото ще отнеме малко обяснения, но по същество това е синтактична захар за получаване и задаване на предпочитания. (Всъщност това е опростяване на неговата функционалност, тъй като системата за предпочитания ще запази стойности, различни от стандартните за съществуващи или нови предпочитания в базата данни, за всеки клас ActiveRecord с колона :preference но не е нужно да знаете това.)

Ето една от тези опции в действие:

module Spree class Calculator

Калкулаторите контролират всякакви неща в Spree - разходи за доставка, промоции, корекции на цените на продуктите - така че наличието на механизъм за тяхното заместване по този начин увеличава разширяемостта на двигателя.

Един от многото начини, по които можете да замените настройките по подразбиране за тези предпочитания, е в рамките на инициализатор в основното приложение Rails:

# config/initializergs/spree.rb Spree::Config do |config| config.admin_interface_logo = 'company_logo.png' end

Ако сте прочели RailsGuide за двигатели , разгледали техните дизайнерски модели или сами сте изградили Двигател, ще разберете, че е тривиално да изложите сетер в инициализационен файл, който някой да използва. Така че може би се чудите, защо цялата суматоха със системата за настройка и предпочитания? Не забравяйте, че системата за предпочитания решава проблем с домейн за Spree. Включването в процеса на инициализация и получаването на достъп до рамката Rails може да ви помогне да отговорите на вашите изисквания по поддържаем начин.

Този модел на проектиране на двигателя се фокусира върху използването на рамката Rails като константа между многото му движещи се части за съхраняване на настройки, които (обикновено) не се променят по време на изпълнение, но се променят между инсталациите на приложения.

Ако някога сте се опитвали бял етикет приложение Rails, може да сте запознати с този сценарий на предпочитания и да сте почувствали болката от обърканите таблици „настройки“ на базата данни в рамките на дълъг процес на настройка за всяко ново приложение. Сега знаете, че е наличен различен път и това е страхотно - петица!

РафинерияCMS

Система за управление на съдържанието с отворен код за Rails

Конвенция за конфигурация някой? Rails Engines понякога може да изглежда по-скоро като упражнение в конфигурация, но RefineryCMS помни част от магията на Rails. Това е цялото съдържание на lib директория:

# lib/refinerycms.rb require 'refinery/all' # lib/refinery/all.rb %w(core authentication dashboard images resources pages).each do |extension| require 'refinerycms-#{extension}' end

Еха. Ако не можете да кажете по това, екипът на Рафинерията наистина знае какво прави. Те се търкалят с концепцията за extension което по същество е друг двигател. Подобно на Spree, той има обхващащ шевове, но използва само два шева и обединява колекция от двигатели, за да предостави пълния си набор от функционалности.

Разширенията също се създават от потребителите на Двигателя, за да създадат свое собствено смесване на CMS функции за блогове, новини, портфолио, препоръки, запитвания и др. (Дълъг списък), всички включени в основната RefineryCMS.

Този дизайн може да привлече вниманието ви заради модулния си подход, а Рафинерията е чудесен пример за този модел на проектиране на Rails. 'Как работи?' Чувам, че питате.

core engine очертава няколко куки, които другите двигатели да използват:

# core/lib/refinery/engine.rb module Refinery module Engine def after_inclusion(&block) if block && block.respond_to?(:call) after_inclusion_procs << block else raise 'Anything added to be called after_inclusion must be callable (respond to #call).' end end def before_inclusion(&block) if block && block.respond_to?(:call) before_inclusion_procs << block else raise 'Anything added to be called before_inclusion must be callable (respond to #call).' end end private def after_inclusion_procs @@after_inclusion_procs ||= [] end def before_inclusion_procs @@before_inclusion_procs ||= [] end end end

Както можете да видите before_inclusion и after_inclusion просто съхранявайте списък с процесори, които ще бъдат стартирани по-късно. Процесът на включване на Refinery разширява заредените в момента приложения Rails с контролери и помощници на Refinery. Ето един в действие:

# authentication/lib/refinery/authentication/engine.rb before_inclusion do [Refinery::AdminController, ::ApplicationController].each do |c| Refinery.include_once(c, Refinery::AuthenticatedSystem) end end

Сигурен съм, че сте вложили методи за удостоверяване във вашия ApplicationController и AdminController преди това е програмен начин за това.

Разглеждането на останалата част от този файл на Authentication Engine ще ни помогне да извлечем няколко други ключови компонента:

module Refinery module Authentication class Engine <::Rails::Engine extend Refinery::Engine isolate_namespace Refinery engine_name :refinery_authentication config.autoload_paths += %W( #{config.root}/lib ) initializer 'register refinery_user plugin' do Refinery::Plugin.register do |plugin| plugin.pathname = root plugin.name = 'refinery_users' plugin.menu_match = %r{refinery/users$} plugin.url = proc { Refinery::Core::Engine.routes.url_helpers.admin_users_path } end end end config.after_initialize do Refinery.register_extension(Refinery::Authentication) end # ... end end

Под капака разширенията за рафинерия използват Plugin система. initializer стъпка ще изглежда позната от анализа на кода на Spree, тук просто се срещаме с register изисквания за методи, които да бъдат добавени към списъка на Refinery::Plugins че core разширението проследява и Refinery.register_extension просто добавя името на модула към списък, съхранен в клас за достъп.

Ето шок: Refinery::Authentication class наистина е обвивка около Devise, с известна персонализация. Така че костенурките са чак до долу!

Разширенията и приставките са концепции, които Рафинерията е разработила, за да поддържа богатата им екосистема от приложения за мини релси и инструменти - помислете rake generate refinery:engine Моделът на дизайна тук се различава от Spree чрез налагане на допълнителен API около Rails Engine, за да подпомогне управлението на техния състав.

Идиомът „Rails Way“ е в основата на Рафинерията, все по-присъстващ в техните приложения за мини-релси, но отвън не бихте знаели това. Проектирането на граници на ниво състав на приложението е също толкова важно, може би и по-важно от създаването на чист API за вашите класове и модули, използвани във вашите Rails приложения.

Опаковането на код, над който нямате пряк контрол, е често срещан модел, това е предвидливост при намаляване на времето за поддръжка, когато този код се промени, ограничавайки броя на местата, които ще ви трябват, за да направите изменения, за да поддържате надстройки. Прилагането на тази техника заедно с функционалността на разделянето създава гъвкава платформа за композиране и ето пример от реалния свят, който седи точно под носа ви - трябва да обичате отворен код!

Заключение


Видяхме четири подхода за проектиране на модели на Rails engine чрез анализ на популярни скъпоценни камъни, използвани в реални приложения. Струва си да прочетете техните хранилища, за да се поучите от богат опит, вече приложен и повторен. Застанете на раменете на гиганти.

В това ръководство за Rails се фокусирахме върху дизайнерските модели и техники за интегриране на Rails Engines и приложенията Rails на крайните потребители, така че да можете да добавите знанията за тях към вашия Релсов инструмент колан .

Надявам се, че сте научили толкова, колкото и аз от прегледа на този код и се чувствате вдъхновени да дадете шанс на Rails Engines, когато отговарят на сметките. Изключително благодаря на поддръжниците и сътрудниците на скъпоценните камъни, които прегледахме. Страхотна работа хора!

Свързани: Съкращаване на клеймото за време: Приказка ActiveRecord за Ruby on Rails

Как да коригирате изтощаването на батерията на iPhone

Съхраняване

Как да коригирате изтощаването на батерията на iPhone
Директор на бизнес операциите

Директор на бизнес операциите

Други

Популярни Публикации
Как да снимате по-интересни плажни снимки на iPhone
Как да снимате по-интересни плажни снимки на iPhone
WordPress Непрекъснато внедряване и контрол на версиите с Bitbucket
WordPress Непрекъснато внедряване и контрол на версиите с Bitbucket
Edge на дизайнера - Общ преглед на приставките за Photoshop
Edge на дизайнера - Общ преглед на приставките за Photoshop
Как да изградим култура в отдалечени екипи
Как да изградим култура в отдалечени екипи
Как да използвате негативното пространство във фотографията, за да трансформирате своя кадър
Как да използвате негативното пространство във фотографията, за да трансформирате своя кадър
 
Изграждане на междуплатформени приложения с Xamarin: перспектива на разработчика за Android
Изграждане на междуплатформени приложения с Xamarin: перспектива на разработчика за Android
Ролята на цвета в UX
Ролята на цвета в UX
Как да прехвърляте снимки от вашия Mac или Windows компютър на вашия iPhone
Как да прехвърляте снимки от вашия Mac или Windows компютър на вашия iPhone
Колко дълго може да оцелее вашият стартъп без финансов директор на пълен работен ден?
Колко дълго може да оцелее вашият стартъп без финансов директор на пълен работен ден?
Запознайте се с Volt, обещаваща Ruby рамка за динамични приложения
Запознайте се с Volt, обещаваща Ruby рамка за динамични приложения
Категории
Разпределени ЕкипиИнструменти И УроциПроцес И ИнструментиИнвеститори И ФинансиранеUi DesignФинансови ПроцесиВъзходът На ДистанционнотоПроцес На ПроектиранеРедактиранеУеб Интерфейс

© 2023 | Всички Права Запазени

socialgekon.com