Rails和类变量:这会在用户和服务器调用中持续存在吗?

时间:2012-04-09 15:01:45

标签: ruby-on-rails ruby ruby-on-rails-3

我们正在使用Rails 3.0.6。

以下代码是否会在Rails中的页面加载和用户中持续存在?或者每次请求都重新定义?代码位于控制器的顶部。

@@list = []

hero = {}
hero['name'] = 'so'
hero['superpowers'] = ['coding', 'qa', 'spec_writing']
@@list.push hero

hero2 = {}
hero2['name'] = 'so2'
hero2['superpowers'] = ['coding']
@@list.push hero2
... more Hashes pushed into @@list

该列表每月只更改一次,我们希望高效快速地将此数据提供给页面请求。我们最终将使用Rails.cache从数据库中读取数据,但我们现在正在使用以下方法(假设它有效)。

5 个答案:

答案 0 :(得分:10)

在开发中,默认行为是在每个请求上重新加载类,从而重置您的类变量。但是,在生产中,类被初始化一次,因此类变量将在多个请求和多个会话中持续存在。

你应该尽快采用适当的缓存技术。显然,在重新启动应用程序时,您不能将该值保留在类的 reloading 之外。此外,如果Web服务器是多线程的(可能是多线程的),它可能在不同的线程上运行应用程序的多个实例,这些线程共享类变量,可能会造成不一致请求。

答案 1 :(得分:1)

我刚刚遇到同样的问题并发现了这篇文章。我知道这是一个老问题,但是发布我的回答以防其他人面临类似的问题...

我认为对于因某些原因无法使用数据库 Rails.cache 的情况,那么放置这些值的最佳位置是Application类。只需定义一些属性并初始化它。然后就像 Rails.application.heros 一样轻松访问它。下面快速而肮脏的样本:

在config / application.rb

module YourRailsApp
  class Application < Rails::Application
    attr_reader :heros

    initializer "init heros" do 
      @heros = []

      hero = {}
      hero['name'] = 'so'
      hero['superpowers'] = ['coding', 'qa', 'spec_writing']
      @heros.push hero

      hero2 = {}
      hero2['name'] = 'so2'
      hero2['superpowers'] = ['coding']

      @heros.push hero2
    end

    #Other application sutff...
  end
end

答案 2 :(得分:0)

我有时会使用我所谓的 穷人的缓存

它的工作原理如下:

    在初始值设定项中
  • ,添加:MY_CACHE_HASH = {}

  • 您想要的任何地方:MY_CACHE_HASH[:foo] = :bar

  • 只要您需要MY_CACHE_HASH[:foo] #=> :bar

我不推荐它:如果你的服务器崩溃你会怎么做?

答案 3 :(得分:0)

如果您有数据表示在运行rails时将不会更改,则可以使用@@class_variable

请记住(在默认开发配置中)控制器类会在每次请求时重新加载,因此如果您需要说,从文件中读取数据,请考虑将代码初始化为config / application .rb位于$globalCONSTANT_VAR

答案 4 :(得分:0)

所以你所描述的是一个不是数据库的数据结构。我认为让代码“永不”改变而不是数据库中的项目是完全合理的。

例如,你可以:

在app / models / hero.rb

class Hero
  @@all_heros = []
  def self.all_heros
    @@all_heros
  end
  def self.add_hero(hero)
    @@all_heros << hero
  end
  def initialize(name, superpowers=[])
    @name = name
    @superpowers = superpowers
  end
end

# this will get executed on load
Hero.add_hero( Hero.new("so", ['coding', 'qa', 'spec_writing']))

然后在您的代码中,您将访问:

@heros = Hero.all_heros

以后,如果需要,可以换出数据库支持的商店。