ruby-on-rails - 如何创建特定于 Rails 的 Rubygem?
问题描述
我们正在构建一个聊天服务,人们可以在他们的代码中使用它。
在我们正在构建的工具中,我们制作了一个 Ruby gem,让人们可以快速将聊天窗口添加到他们的 Ruby Web 应用程序中。
不过,我们想创建一个特定于 Rails 的包装器,因为目前用户必须手动调用.html_safe
.
如何在 Ruby gem 中使用这些特定于 Rails 的特性?我听说这可能被称为“Railsties”,但我无法找到任何关于这些以及如何使用它们的综合文档。
具体来说,我们希望:
- 调用
html_safe
一些字符串输出,这样用户就不必手动执行此操作。 - 将一些配置设置放在一个文件中,
config/initializers/some_name.rb
而不必内联指定这些。 - 可能会创建一个生成器,用户可以运行该生成器来自动填充此初始化程序。
我们如何使用这些功能?我们可以在 gem 中包含其他一些 gem 依赖项来访问这些功能吗?
解决方案
引擎可以被认为是为其主机应用程序提供功能的微型应用程序。Rails 应用程序实际上只是一个“增压”引擎,Rails::Application 类从 Rails::Engine 继承了许多行为。
https://guides.rubyonrails.org/engines.html
引擎可以包含模型、控制器、路由、生成器、中间件和您可以安装在主机应用程序中的任意代码。引擎通常打包为 gem。
例如,Devise 是一个提供授权的 Rails 引擎。
Rails 有一个用于创建引擎的生成器命令:
rails plugin new chatty --mountable
对于这个例子,我们称之为健谈。
由于引擎安装在 Rails 应用程序中,因此您可以完全访问 Rails 堆栈(例如.html_safe
)。这也意味着您通过将引擎安装在虚拟应用程序中来测试引擎。
如果您已将应用程序打包为 gem,则只需将其添加到 Gemfile 即可将其挂载到主机应用程序中。
要使您的引擎可配置,您可以遵循“MyGem.configure 模式”:
# lib/chatty.rb
module Chatty
class << self
attr_accessor :configuration
end
def self.configure
self.configuration ||= Configuration.new
yield(configuration)
end
class Configuration
attr_accessor :foo
def initialize
@foo = 'some_value'
end
end
end
要创建用户配置文件,请使用生成器:
# lib/generators/chatty/install/install_generator.rb
module Chatty
class InstallGenerator < Rails::Generators::Base
source_root File.expand_path('templates', __dir__)
desc "Creates a Chatty initializer."
def copy_initializer
template 'chatty.rb', 'config/initializers/chatty.rb'
end
end
end
和一个代码模板:
# /lib/generators/chatty/install/templates/chatty.rb
Chatty.configure do |config|
config.foo = "bar"
end
您现在可以运行rails g chatty:install
,它将在主机应用程序中创建文件。