2016-07-29 96 views
0

我想存储一个全局变量,因此每次参考模型时都不会碰到数据库。存储一个包含模型集合的全局变量

我应该在初始化程序中执行此操作还是有其他方法?

$rules = Rule.all 

该数据不会改变,除非我改变的代码库,因此是罚款只能在应用程序重新加载时刷新。

我有什么选择?

我想我可以在我的控制器也这样做:

$rules ||= Rule.all 

是否有一个“最佳做法”有关呢?

+0

这是一个坏主意。那么首先需要知道为什么要缓存这个值?你想缓存启动时的价值? –

+0

如果数据是静态的,为什么使用数据库而不是简单的Ruby哈希或数组? – meagar

+0

@ArupRakshit在启动时可以。 – Blankman

回答

1

好吧,然后在config/initializers/目录内创建一个文件,如load_rules.rb。在里面,写下类似的东西:

ActiveSupport.on_load(:active_record) do 
    RULES = Rule.all 
end 

现在在你想使用的任何地方使用这个常量。

+0

为什么当他没有对数据库做任何事情时,他甚至会使用ActiveRecord对象? – siegy22

+0

@RaVeN他使用术语_model_。我想要存储一个全局变量这一行,所以我不会在每次引用模型时都碰到数据库,这足以让我总结这个解决方案。但正如我在答复评论中所说的那样,对于静态数据不需要模型。我注意到后来的设计气味。 –

+0

等等,所以你说'模型'总是一个ActiveRecord模型? – siegy22

0

我认为你不想使用数据库这样的事情。您应该将这些值存储为对象的数组,并使用Rails.app.config.x命名空间:

所以你的模型看起来像:

#app/models/rule.rb 
class Rule 
    attr_reader :name 

    def initialize(name:) 
    @name = name 
    end 
end 

和你的初始化:

# config/initializers/rules_initializer.rb 
Rails.application.config.x.rules = [ 
             Rule.new(name: "Admin"), 
             ... 
            ] 
+0

该方法需要在规则集更改时修改代码。 –

+0

创建对象,'seeds.rb'文件是我认为很好的。 –

+0

@NicNilov如果集合发生了变化,您将不会更改任何代码吗?存储在数据库中? – siegy22

1

我建议使用用一种方法包装低级缓存:

class ApplicationCotroller < ActionController::Base 
    # ... 

    def all_rules 
     Rails.cache.fetch("all_rules") do 
     Rule.all 
     end 
    end 

    # ... 
end 

depends在您的使用案例中,该方法可以放置在单个类中而不是ApplicationController或混入Module中。

此方法的主要优点是您可以轻松地重新加载规则,而无需通过从控制台中删除缓存键来重新启动服务器。虽然你明确地将此标记为非关键方面,但我认为它增加了一些便利。

+0

我喜欢你的缓存方法! +1。原因是我们可以在不重新启动的情况下刷新数据。好主意! –

+0

但是,如果我想在其他环境中使用它,那么1件事是什么?您可能需要放入一些初始化程序类型,以便进行全局访问。 –

+1

是的,正如我所提到的,根据用例可以放在其他地方,初始化程序是一种选择。 –