ruby-on-rails - 在 Rails 启动期间创建类的实例

标签 ruby-on-rails ruby class instance

我试图在 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/

相关文章:

ruby-on-rails - Prawn gem 支持阿拉伯语吗?

ruby-on-rails - 语法错误,意外 ',',期待 ')' RoR

ruby-on-rails - 丰富连接表的嵌套属性,使用 simple_form Rails

ruby-on-rails - 如何根据我在 Rails 中的响应状态代码跳过 after_filter 回调?

ruby-on-rails - 将文本字符串转换为任何有效的 Ruby 格式时间

ruby - 如何在 ubuntu 12.0.4 上将 usr/local/bin 添加到路径环境变量?

java - Java 类中的数组?

android onclicklistener 在类里面有按钮吗?

Python:从该类内部对作为该类数据成员的函数进行多处理的有效解决方法

mysql - ruby mysql 连接错误