เหตุใด Rails Engines จึงไม่ถูกใช้บ่อยขึ้น? ฉันไม่รู้คำตอบ แต่ฉันคิดว่าลักษณะทั่วไปของ“ ทุกอย่างเป็นเครื่องยนต์” ได้ซ่อนโดเมนปัญหาที่พวกเขาสามารถช่วยแก้ไขได้
ที่ยอดเยี่ยม เอกสารคู่มือราง สำหรับการเริ่มต้นใช้งาน Rails Engines ให้อ้างอิงถึงตัวอย่างยอดนิยม 4 ตัวอย่างของการใช้งาน Rails Engine: Forem, Devise, Spree และ RefineryCMS นี่คือกรณีการใช้งานในโลกแห่งความเป็นจริงที่ยอดเยี่ยมสำหรับ Engines โดยใช้วิธีการที่แตกต่างกันในการผสานรวมกับแอปพลิเคชัน Rails
การตรวจสอบบางส่วนของวิธีการกำหนดค่าและประกอบอัญมณีเหล่านี้จะให้ขั้นสูง นักพัฒนา Ruby on Rails ความรู้ที่มีค่าเกี่ยวกับรูปแบบหรือเทคนิคที่พยายามและทดสอบในป่าดังนั้นเมื่อถึงเวลาคุณสามารถมีตัวเลือกพิเศษบางอย่างเพื่อประเมิน
ฉันคาดหวังว่าคุณจะมีความคุ้นเคยอย่างคร่าวๆเกี่ยวกับวิธีการทำงานของเครื่องยนต์ดังนั้นหากคุณรู้สึกว่ามีบางอย่างไม่ได้เพิ่มขึ้นโปรดอ่านคู่มือ Rails ที่ยอดเยี่ยมที่สุด เริ่มต้นใช้งานเครื่องยนต์ .
โดยไม่ต้องกังวลใจอีกต่อไปเรามาร่วมผจญภัยในโลกแห่งตัวอย่างเครื่องยนต์ Rails กันเถอะ!
โหนด js ทำการโทรแบบอะซิงโครนัสแบบซิงโครนัส
เครื่องมือสำหรับ Rails ที่มุ่งหวังให้เป็นระบบฟอรัมเล็ก ๆ ที่ดีที่สุดเท่าที่เคยมีมา
อัญมณีนี้เป็นไปตามทิศทางของ Rails Guide on Engines ไปยังตัวอักษร เป็นตัวอย่างที่มีขนาดใหญ่และการอ่านที่เก็บข้อมูลจะทำให้คุณทราบว่าคุณสามารถยืดการตั้งค่าพื้นฐานได้ไกลเพียงใด
เป็นอัญมณีเครื่องยนต์เดียวที่ใช้เทคนิคสองสามอย่างเพื่อรวมเข้ากับแอปพลิเคชันหลัก
module ::Forem class Engine ส่วนที่น่าสนใจคือ Decorators.register!
วิธีการเรียนที่เปิดเผยโดยอัญมณีตกแต่ง มันห่อหุ้มไฟล์การโหลดที่จะไม่รวมอยู่ในกระบวนการโหลดอัตโนมัติของ Rails คุณอาจจำได้ว่าใช้ Explicit 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
ตัวแปรที่ถูกตั้งค่าในไฟล์ initializer:
Forem.user_class = 'User'
คุณทำได้โดยใช้ mattr_accessor
แต่ทั้งหมดนี้อยู่ใน Rails Guide ดังนั้นฉันจะไม่พูดซ้ำที่นี่ ด้วยสิ่งนี้ 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 นั้นเป็นอย่างไร
Decorating เป็นชื่อของเกมในการใช้งาน Engine เริ่มต้น ในฐานะผู้ใช้ปลายทางของ gem คุณสามารถแทนที่โมเดลมุมมองและคอนโทรลเลอร์ได้โดยสร้างคลาสเวอร์ชันของคุณเองโดยใช้เส้นทางไฟล์และรูปแบบการตั้งชื่อไฟล์ที่วางไว้ในมัณฑนากรเจม README แม้ว่าจะมีค่าใช้จ่ายที่เกี่ยวข้องกับแนวทางนี้โดยเฉพาะอย่างยิ่งเมื่อ Engine ได้รับการอัปเกรดเวอร์ชันหลัก - การดูแลรักษาอุปกรณ์ตกแต่งของคุณให้ทำงานได้อย่างรวดเร็ว ฉันไม่ได้อ้างถึง Forem ที่นี่ฉันเชื่อว่าพวกเขามีความแน่วแน่ในการรักษาฟังก์ชันหลักที่แน่นหนา แต่โปรดคำนึงถึงสิ่งนี้หากคุณสร้าง Engine และตัดสินใจที่จะทำการยกเครื่อง
ขอสรุปสิ่งนี้: นี่คือรูปแบบการออกแบบเอ็นจิน Rails เริ่มต้นโดยอาศัยผู้ใช้ปลายทางในการตกแต่งมุมมองคอนโทรลเลอร์และโมเดลพร้อมกับกำหนดการตั้งค่าพื้นฐานผ่านไฟล์การเริ่มต้น สิ่งนี้ใช้ได้ดีกับฟังก์ชันการทำงานที่เน้นและเกี่ยวข้อง
ภาษิต
คุณจะพบว่า Engine นั้นคล้ายกับแอปพลิเคชัน Rails มากโดยมี views
, controllers
และ models
ไดเรกทอรี Devise เป็นตัวอย่างที่ดีในการห่อหุ้มแอปพลิเคชันและแสดงจุดรวมที่สะดวก มาดูวิธีการทำงานกัน
คุณจะจดจำบรรทัดของโค้ดเหล่านี้ได้หากคุณเป็นผู้พัฒนา Rails มานานกว่าสองสามสัปดาห์:
class User แต่ละพารามิเตอร์ส่งผ่านไปที่ devise
วิธีการแสดงถึงโมดูลภายใน Devise Engine มีโมดูลเหล่านี้ 10 โมดูลที่สืบทอดมาจาก ActiveSupport::Concern
ที่คุ้นเคย สิ่งเหล่านี้ขยาย User
ของคุณ โดยเรียกใช้ devise
วิธีการภายในขอบเขต
การมีจุดรวมประเภทนี้มีความยืดหยุ่นมากคุณสามารถเพิ่มหรือลบพารามิเตอร์เหล่านี้เพื่อเปลี่ยนระดับการทำงานที่คุณต้องการให้ Engine ดำเนินการ นอกจากนี้ยังหมายความว่าคุณไม่จำเป็นต้องฮาร์ดโค้ดรุ่นที่คุณต้องการใช้ภายในไฟล์ initializer ตามที่แนะนำโดย Rails Guide on Engines กล่าวอีกนัยหนึ่งไม่จำเป็น:
Devise.user_model = 'User'
สิ่งที่เป็นนามธรรมนี้ยังหมายความว่าคุณสามารถใช้สิ่งนี้กับโมเดลผู้ใช้มากกว่าหนึ่งแบบภายในแอปพลิเคชันเดียวกัน (เช่น admin
และ user
) ในขณะที่วิธีการกำหนดค่าไฟล์จะทำให้คุณเชื่อมโยงกับโมเดลเดียวด้วยการพิสูจน์ตัวตน นี่ไม่ใช่จุดขายที่ใหญ่ที่สุด แต่แสดงให้เห็นถึงวิธีอื่นในการแก้ปัญหา
ค่าใช้จ่ายในการจ้างเครื่องคิดเลขพนักงาน
ประดิษฐ์ขยาย 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 และการเปิดเผยจุดกำหนดค่าเพื่อรวมหรือยกเว้นสิ่งเหล่านี้ภายในขอบเขตที่กำหนด เครื่องยนต์ที่สร้างขึ้นในลักษณะนี้สะดวกสำหรับผู้ใช้ซึ่งเป็นปัจจัยสนับสนุนความสำเร็จและความนิยมของ Devise และตอนนี้คุณก็รู้วิธีทำเช่นกัน!
สนุกสนาน
Spree ต้องใช้ความพยายามอย่างมากในการนำแอปพลิเคชันเสาหินของพวกเขามาควบคุมด้วยการเปลี่ยนไปใช้ Engines การออกแบบสถาปัตยกรรมที่พวกเขาใช้อยู่ในขณะนี้คืออัญมณี“ Spree” ที่มีอัญมณี Engine มากมาย
Engines เหล่านี้สร้างพาร์ติชันในลักษณะการทำงานที่คุณอาจคุ้นเคยกับการมองเห็นภายในแอปพลิเคชันเสาหินหรือกระจายไปตามแอปพลิเคชัน:
เทมเพลตเอกสารการออกแบบซอฟต์แวร์อย่างง่าย
- spree_api (RESTful API)
- spree_frontend (คอมโพเนนต์ที่หันหน้าเข้าหาผู้ใช้)
- spree_backend (พื้นที่ผู้ดูแลระบบ)
- spree_cmd (เครื่องมือบรรทัดคำสั่ง)
- spree_core (โมเดลและจดหมายซึ่งเป็นส่วนประกอบพื้นฐานของ Spree ที่ขาดไม่ได้)
- spree_sample (ข้อมูลตัวอย่าง)
อัญมณีที่ล้อมรอบจะเย็บสิ่งเหล่านี้เข้าด้วยกันทำให้นักพัฒนามีตัวเลือกในระดับฟังก์ชันที่ต้องการ ตัวอย่างเช่นคุณสามารถเรียกใช้โดยใช้เพียง spree_core
สร้างและปิดอินเทอร์เฟซของคุณเอง
Spree gem หลักต้องการเอ็นจิ้นเหล่านี้:
# 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 มีโค้ดที่น่าทึ่งมากมายดังนั้นเรามาดูวิธีที่พวกเขาใช้การเริ่มต้นเพื่อแบ่งปันการกำหนดค่าระหว่าง Engines และ Rails Application หลัก
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.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
มันแสดง :preferences
ตัวแปรที่ตั้งค่าเป็นอินสแตนซ์ใหม่ของ Spree::AppConfiguration
คลาสซึ่งจะใช้ preference
วิธีการที่กำหนดไว้ใน Preferences::Configuration
คลาสเพื่อตั้งค่าตัวเลือกด้วยค่าเริ่มต้นสำหรับการกำหนดค่าแอปพลิเคชันทั่วไป:
module Spree class AppConfiguration ฉันจะไม่แสดง Preferences::Configuration
เนื่องจากต้องใช้เวลาอธิบายเล็กน้อย แต่โดยพื้นฐานแล้วมันคือน้ำตาลที่เป็นประโยคสำหรับการรับและการตั้งค่า (ในความเป็นจริงนี่เป็นการลดความซับซ้อนของฟังก์ชันการทำงานเนื่องจากระบบการตั้งค่าจะบันทึกค่าอื่นที่ไม่ใช่ค่าเริ่มต้นสำหรับค่ากำหนดที่มีอยู่หรือค่ากำหนดใหม่ในฐานข้อมูลสำหรับคอลัมน์ ActiveRecord
ใด ๆ ที่มีคอลัมน์ :preference
- แต่คุณไม่จำเป็นต้องรู้เรื่องนั้น)
นี่คือหนึ่งในตัวเลือกที่ใช้งานได้จริง:
module Spree class Calculator เครื่องคิดเลขจะควบคุมสิ่งต่างๆใน Spree ไม่ว่าจะเป็นค่าขนส่งโปรโมชั่นการปรับราคาสินค้าดังนั้นการมีกลไกในการแลกเปลี่ยนสินค้าในลักษณะนี้จะเพิ่มความสามารถในการขยายของเครื่องยนต์
หนึ่งในหลาย ๆ วิธีที่คุณสามารถแทนที่การตั้งค่าเริ่มต้นสำหรับค่ากำหนดเหล่านี้คือภายใน initializer ในแอปพลิเคชัน Rails หลัก:
# config/initializergs/spree.rb Spree::Config do |config| config.admin_interface_logo = 'company_logo.png' end
หากคุณได้อ่านไฟล์ RailsGuide เกี่ยวกับเครื่องยนต์ พิจารณารูปแบบการออกแบบของพวกเขาหรือสร้าง Engine ด้วยตัวคุณเองคุณจะรู้ว่ามันเป็นเรื่องเล็กน้อยที่จะเปิดเผยตัวตั้งค่าในไฟล์ initializer สำหรับคนที่จะใช้ ดังนั้นคุณอาจสงสัยว่าทำไมต้องยุ่งยากกับระบบการตั้งค่าและความชอบ? อย่าลืมว่าระบบการตั้งค่ากำหนดสามารถแก้ปัญหาโดเมนสำหรับ Spree ได้ การเข้าสู่กระบวนการเริ่มต้นและการเข้าถึงเฟรมเวิร์ก Rails จะช่วยให้คุณสามารถตอบสนองความต้องการของคุณได้ในแบบที่ดูแลรักษาได้
รูปแบบการออกแบบเครื่องยนต์นี้มุ่งเน้นไปที่การใช้เฟรมเวิร์ก Rails เป็นค่าคงที่ระหว่างชิ้นส่วนที่เคลื่อนไหวจำนวนมากเพื่อจัดเก็บการตั้งค่าที่ไม่ (โดยทั่วไป) เปลี่ยนแปลงในขณะรันไทม์ แต่จะเปลี่ยนระหว่างการติดตั้งแอปพลิเคชัน
หากคุณเคยพยายามที่จะ ป้ายขาว แอปพลิเคชัน Rails คุณอาจคุ้นเคยกับสถานการณ์การตั้งค่านี้และรู้สึกเจ็บปวดกับตาราง 'การตั้งค่า' ฐานข้อมูลที่ซับซ้อนภายในกระบวนการตั้งค่าที่ยาวนานสำหรับแต่ละแอปพลิเคชันใหม่ ตอนนี้คุณรู้แล้วว่ามีเส้นทางที่แตกต่างออกไปและมันยอดเยี่ยม - ไฮไฟว์!
โรงกลั่น CMS
อนุสัญญาเหนือใคร? Rails Engines อาจดูเหมือนเป็นการออกกำลังกายในการกำหนดค่าในบางครั้ง แต่ RefineryCMS จะจำเวทมนตร์ของ Rails นั้นได้ นี่คือเนื้อหาทั้งหมดของ lib
ไดเรกทอรี:
ใครจ่าย uber หรือ lyft มากกว่า 2016
# 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 ที่มีอัญมณีเย็บปะติดปะต่อกัน แต่ใช้เพียงสองเข็มและรวบรวมชุดเครื่องยนต์เพื่อมอบฟังก์ชันการทำงานที่ครบถ้วน
ส่วนขยายยังถูกสร้างขึ้นโดยผู้ใช้ Engine เพื่อสร้างฟีเจอร์ CMS สำหรับบล็อกข่าวสารผลงานข้อความรับรองการสอบถาม ฯลฯ (เป็นรายการยาว ๆ ) ซึ่งทั้งหมดเชื่อมโยงเข้ากับ RefineryCMS หลัก
การออกแบบนี้อาจได้รับความสนใจจากคุณสำหรับแนวทางแบบแยกส่วนและโรงกลั่นเป็นตัวอย่างที่ดีของรูปแบบการออกแบบรางนี้ “ มันทำงานอย่างไร” ฉันได้ยินคุณถาม
core
เอนจิ้นแมปตะขอสองสามอันสำหรับเอนจินอื่น ๆ ที่จะใช้:
# 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
เพียงจัดเก็บรายการ procs ที่จะเรียกใช้ในภายหลัง กระบวนการรวมการกลั่นจะขยายแอปพลิเคชัน Rails ที่โหลดอยู่ในปัจจุบันด้วยตัวควบคุมและตัวช่วยของโรงกลั่น นี่คือหนึ่งในการดำเนินการ:
# 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
คลาสเป็นกระดาษห่อหุ้มรอบ ๆ Devise โดยมีการปรับแต่งบางอย่าง มันก็เลยเต่าลงไป!
ส่วนขยายและปลั๊กอินเป็นแนวคิดที่โรงกลั่นได้พัฒนาขึ้นเพื่อรองรับระบบนิเวศของแอปมินิรางและเครื่องมือ - think rake generate refinery:engine
รูปแบบการออกแบบที่นี่แตกต่างจาก Spree ด้วยการกำหนด API เพิ่มเติมรอบ ๆ Rails Engine เพื่อช่วยในการจัดการองค์ประกอบ
สำนวน“ The Rails Way” เป็นหัวใจหลักของโรงกลั่นซึ่งมักจะมีอยู่ในแอปมินิรางมากขึ้น แต่จากภายนอกคุณจะไม่รู้ การออกแบบขอบเขตในระดับองค์ประกอบของแอปพลิเคชันมีความสำคัญอาจมากกว่าการสร้าง API ที่สะอาดสำหรับคลาสและโมดูลของคุณที่ใช้ภายในแอปพลิเคชัน Rails ของคุณ
การห่อรหัสที่คุณไม่มีการควบคุมโดยตรงเป็นรูปแบบทั่วไปเป็นการมองการณ์ไกลในการลดเวลาในการบำรุงรักษาเมื่อรหัสนั้นมีการเปลี่ยนแปลง จำกัด จำนวนสถานที่ที่คุณจะต้องแก้ไขเพื่อรองรับการอัปเกรด การใช้เทคนิคนี้ควบคู่ไปกับฟังก์ชันการแบ่งพาร์ติชันจะสร้างแพลตฟอร์มที่ยืดหยุ่นสำหรับการจัดองค์ประกอบภาพและนี่คือตัวอย่างโลกแห่งความจริงที่นั่งอยู่ใต้จมูกของคุณ - ต้องรักโอเพ่นซอร์ส!
สรุป
เราได้เห็นสี่วิธีในการออกแบบรูปแบบเครื่องยนต์ Rails โดยการวิเคราะห์อัญมณียอดนิยมที่ใช้ในการใช้งานจริง เป็นสิ่งที่ควรค่าแก่การอ่านผ่านที่เก็บของพวกเขาเพื่อเรียนรู้จากประสบการณ์มากมายที่นำไปใช้แล้วและทบทวนซ้ำ ยืนบนบ่าของยักษ์
ในคู่มือ Rails นี้เราได้มุ่งเน้นไปที่รูปแบบการออกแบบและเทคนิคในการผสานรวม Rails Engines และแอปพลิเคชัน Rails ของผู้ใช้เพื่อให้คุณสามารถเพิ่มความรู้เหล่านี้ให้กับ สายพานเครื่องมือราง .
ฉันหวังว่าคุณจะได้เรียนรู้มากพอ ๆ กับฉันจากการตรวจสอบโค้ดนี้และรู้สึกเป็นแรงบันดาลใจที่จะให้โอกาส Rails Engines เมื่อพวกเขาเหมาะสมกับใบเรียกเก็บเงิน ขอขอบคุณอย่างยิ่งสำหรับผู้ดูแลและผู้มีส่วนร่วมกับอัญมณีที่เราตรวจสอบ คนเก่ง!
ที่เกี่ยวข้อง: Timestamp Truncation: ทับทิมบน Rails ActiveRecord Tale