我试图在 Rails 加载时创建一个类的多个实例,并保持这些实例可用。 (我正在从 YAML 文件加载数据,但我已经抽象出这个问题的细节。)我有一个非 ActiveRecord 模型,它带有一个加载数据的 instantiate
类方法。当我从 config.after_initialize
和/或从自定义初始化程序调用 instantiate
时,实例已创建,但到 rails console
完成加载时,他们走了。我在哪里可以实例化数据,以便它在 Rails 控制台(和服务器)中可用?
# app/models/test.rb
class Test
include ActiveModel::Model
attr_accessor :name
class << self
include Enumerable
def each
ObjectSpace.each_object(self).each do |object|
yield object
end
self
end
def find_by_name(input)
find { |object| object.name.to_s == input.to_s }
end
def instantiate
new(name: 'Alice')
new(name: 'Bob')
end
end
def initialize(*parameters)
super(*parameters)
freeze
end
delegate :to_s, to: :name
end
# config/application.rb
module MyApp
class Application < Rails::Application
config.after_initialize do
p "Test instances before after_initialize: #{Test.count}"
Test.instantiate
p "Test instances after after_initialize: #{Test.count}"
end
end
end
# config/initializer/test_initializer.rb
p "Test instances before test_initializer: #{Test.count}"
Test.instantiate
p "Test instances after test_initializer: #{Test.count}"
$ rails console
"Test instances before test_initializer: 2"
"Test instances after test_initializer: 4"
"Test instances before after_initialize: 0"
"Test instances after after_initialize: 2"
Loading development environment (Rails 4.2.6)
irb(main):001:0> Test.count
=> 0
irb(main):002:0> Test.instantiate
=> #<Test:0x007fad2204d8b0 @name="Bob">
irb(main):003:0> Test.count
=> 2
最佳答案
Ruby 垃圾收集器从内存中删除实例。不存在引用新创建的实例的直接链接,因此 Ruby 认为它们是不必要的。
您可以通过添加来尝试:
module MyApp
class Application < Rails::Application
config.after_initialize do
GC.disable # Disable garbage collector
p "Test instances before after_initialize: #{Test.count}"
Test.instantiate
p "Test instances after after_initialize: #{Test.count}"
end
end
end
但是禁用垃圾收集器并不是一个好主意。如果您以某种方式引用实例,它们将不会被清除,并且它们将在启动后通过引用可用。
关于ruby-on-rails - 在 Rails 启动期间创建类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36555283/