Rails中的永久变量

问题描述:

可以说,在我的Rails应用程序的顶部有一个带有一段文本的栏 - 最新的热门交易,计划的停机通知等等。这是一种单独的信息,基本上每个请求都需要访问,并且可能会不时更新。达到此目的的最佳方法是什么?Rails中的永久变量

我想要做的是某种永久性全局变量(可从控制器访问)。

  • 它很少被更新,因此如果在更新后的一段时间内工作人员之间会出现不一致的情况,则不会有任何问题。
  • 另一方面,它应该在服务器故障的情况下保持不变(周期性备份就足够了)。
  • 它会经常被访问,所以它应该尽可能快 - 最好留在内存中。
  • 此外,它只是一种,所以我真的不想用专用的数据库模型来扩大应用程序。

这样的事情在Node.js中很容易,但我找不到在Rails中实现这一点的单一方法。我该怎么办?

编辑

感谢您的答案,到目前为止,但同时他们是鼓舞人心的,我认为我应该强调了一个关键的功能,他们都不见了。 该变量应该可在应用程序内编辑并持久化。尽管可以编辑变量,但在服务器重新启动的情况下,我又回到了默认值 - 这很糟糕。

好的,这就是我所做的。我没有将这个值赋给一个初始化器,而是创建了一个处理它的简单类。变量本身存储在一个预定义的文件中。除了在初始化时读取文件之外,该类在更改值时更新文件,并且还定期重新读取该文件以保持工作人员之间的一致性。我还提供了一些基本的JSON处理和备份功能,让生活更轻松。

任何有兴趣,这里的重要代码:

class Pomegranate 

    def initialize 
    @delay = 30.minutes 
    @path = "db/pomegranate.json" 
    @valid = Time.now - 1 
    validate 
    end 

    def get(*p) 
    validate 
    p.inject(@data) {|object,key| object[key] if object} 
    end 

    def set(*p, q, v) 
    hash = p.inject(@data) {|object,key| object[key]||={}} 
    hash[q] = v 
    end 

    def save 
    @valid = Time.now + @delay 
    File.open(@path,"w") {|f| f.write(@data.to_json)} 
    end 

    private 

    def validate 
    if @valid < Time.now 
     @data = ActiveSupport::JSON.decode(File.read(@path)) rescue {} 
     @valid = Time.now + @delay 
     @valid = Time.now - 1 if @data.empty? 
    end 
    end 

end 

$pom = Pomegranate.new 

来源: Where to put Global variables in Rails 3

尝试把它在你的applicaton.rb这样的:

module MyAppName 
    class Application < Rails::Application 
    YOUR_GLOBAL_VAR = "test" 
    end 
end 

然后你就可以在你的控制器,意见或任何命名空间称之为..

MyAppName::Application::YOUR_GLOBAL_VAR 

另一种方法是使用类似settingslogic的东西。使用settingslogic,您只需创建一个yml配置文件和一个指向配置文件的模型(Settings.rb)。然后你就可以在你的Rails应用程序的任何地方访问这些设置有:

config/initialzers/foo.rb

MYVARIABLE = 'some string' 

在应用程序的任何地方访问

Settings.my_setting 

你可以在初始化声明为一个常数作为MYVARIABLE

+0

如果我以后改变了这个变量,它会在工人之间保持一致吗? – 2012-02-28 23:39:29

+0

不,您可以使用dRuby在所有工作人员之间传递更新。 – rudolph9 2012-05-04 14:30:28

这真的取决于你在找什么。你可以通过把它在你的application_controller.rb

class ApplicationController < ActionController::Base 
    def system_message 
    "Come buy our amazing .99 iphone chocolate bar apps, with 100% more gamification!" 
    end 
end 

这个函数(和字符串)做什么事情都很简单说就是那么在应用程序的任何控制器访问。您还可以在application.rb文件的after_initialize块中指定某些内容。

config.after_initialize do 
    ::MYTEXT = "MY SUPER AMAZING TEXT" 
end 

您还可以在预加载在rails中的initializers目录下创建自己的文件。

所以siteAnnounce.rb

MYANNOUNCEMENT = "NOW LISTEN TO ME!" 

你可能也想看看这个Railscast video about site wide announcements

+0

我倾向于初始值设定项。一个问题是:如果我后来改变这个变量,工人之间是否一致? – 2012-02-28 23:38:53

+0

好吧,因为变量将被硬编码到站点中,并且您需要关闭服务器以部署代码,所以在将所有代码全部备份后都应该保持一致。如果您尝试用某种持续部署系统更改变量,那么我看到您遇到的唯一问题就会发生,但那不是我的专业领域。 – 2012-02-29 04:52:13

我已经开始把常量和变量这样的配置对象,例如

TestApp::Application.config.foo = 'bar' 
TestApp::Application.config.something = { :a => 1, :b => 2 } 

我会将它存储在数据库中并让缓存来处理它。

我觉得在适当的时候,对于那些需要在许多地方共享这个公共值的代码来说,全局变量是很好的,但这是代码,而不是用户视图。
在这种情况下,显然这是因为OP粗体显示为'可由应用程序编辑'。所以我会有一个让用户输入它的视图,它存储在一个数据库表中,然后根据需要调用(如曾经使用过的缓存)。

嗯,我已经遇到了类似的问题。 我的问题是我需要所有级别(MVC)的全局变量。 我们去使用Memcache来存储变量。 也许你可以去找一个类似的解决方案。 作为额外的奖励,您可以在整个程序中进行更改。