我正在编写一个需要一些设置配置的 Rails 引擎,并且还会检查是否在模型上定义了一些必需的属性。lib 中定义它的引擎类如下。
module Kiosk
mattr_accessor :kiosk_class
@@kiosk_class = 'Computer'
mattr_accessor :kiosk_primary_key
@@kiosk_primary_key = 'id'
mattr_accessor :kiosk_type_foreign_key
@@kiosk_type_foreign_key = 'kiosk_type_id'
mattr_accessor :kiosk_name_attribute
@@kiosk_name_attribute = 'name'
mattr_accessor :kiosk_ip_address_attribute
@@kiosk_ip_address_attribute = 'ip_address'
mattr_accessor :kiosk_mac_address_attribute
@@kiosk_mac_address_attribute = 'mac_address'
# Private config and methods
def self.setup
if block_given?
yield self
end
check_fields!
end
def self.required_fields
[@@kiosk_primary_key, @@kiosk_name_attribute, @@kiosk_ip_address_attribute, @@kiosk_mac_address_attribute, @@kiosk_type_foreign_key]
end
def self.check_fields!
failed_attributes = []
instance = @@kiosk_class.constantize.new
required_fields.each do |field|
failed_attributes << field unless instance.respond_to?(field)
end
if failed_attributes.any?
raise "Missing required attributes in #{@@kiosk_class} model: #{failed_attributes.join(', ')}"
end
end
def self.klass
@@kiosk_class.constantize
end
end
模型名称和属性名称可以在所需的初始化程序中配置,该初始化程序执行调用setup
传递配置参数块的工作。那是,
Kiosk.setup do |config|
# The name of the class that stores info about the kiosks
# It should contain the required fields whose names are defined below
# config.kiosk_class = 'Computer'
# The primary key of the kiosk class
# config.kiosk_primary_key = 'id'
# A foreign key in the kiosk class for the kiosk type
# config.kiosk_type_foreign_key = 'kiosk_type_id'
# An attribute containing the name of the kiosk
# config.kiosk_name_attribute = 'name'
# An attribute containing the IP address of the kiosk
# config.kiosk_ip_address_attribute = 'ip_address'
# An attribute containing the MAC address of the kiosk
# config.kiosk_mac_address_attribute = 'mac_address'
end
我在测试过程中遇到的问题是,如果缺少必需的属性,那么调用任何生成器或 Rake 任务也会失败,这意味着甚至无法添加该属性。
我想要的是能够在我的设置中检测它是作为服务器启动的一部分(因此应该进行字段检查)还是作为任何其他 Rails 启动(例如 Rake 任务、生成器等)被调用(和因此应该跳过字段检查)。我觉得必须有一个解决方案,因为启动 Rails 控制台永远不会失败。
或者,如果这是不可能的,您将如何在初始化程序之外执行字段检查,但以保证在服务器启动期间发生并且每次启动仅发生一次的方式执行?
我意识到在了解应用程序在什么上下文下运行之前已经提出了类似的问题(例如,如何在运行“rails generate”时防止初始化程序运行以及仅在“rails server”而不是“rails generate”上运行的Rails 3初始化程序等),但那里提出的解决方案对我的情况不是很有用。