簡體   English   中英

Ruby和Rails:元編程變量成為類方法

[英]Ruby and Rails: Metaprogramming variables to become class methods

我正在創建一個名為Configuration的模型,我有以下代碼,並且我想通過使用元編程使它更加動態。

在用於配置模型的數據庫的表中,我具有以下數據。

---------------------------------------------------------
variable_name as string     |  value in text
                            |
company_name                |  MyCompany
welcome_text                |  Welcome to MyCompany's App!
email_order_text            |  You've just created an account with MyCompany.
year_since                  |  2012
----------------------------------------------------------

class Configuration  < ActiveRecord::Base

    #nothing here yet

end

----------------------------------------------------------

當前,訪問company_name的唯一方法是在rails控制台中執行以下操作:

configuration_company_name = Configuration.find_by_variable_name("company_name")
configuration_company_name.company_name

> "MyCompany"

我認為這是做事的不可接受的方式。 首先,每次有人檢查公司名稱時,它將訪問數據庫。 我認為,如果我可以在應用啟動時加載它,而不必因為它在內存中而再次訪問它,那會更好。 我該如何做些更動態的事情,以便可以像這樣訪問值“ MyCompany”。

Configuration.company_name

> "MyCompany"

這樣做的原因是允許快速定制應用程序。

class Configuration  < ActiveRecord::Base
  # loads all the configuration variables to an in-memory
  # static hash during the first access. 
  def self.[](n)
    @config ||= {}.tap { |h| Configuration.all.each{ h[variable_name] = c.value}}
    @config[n]
  end
end

現在,您可以通過以下方式訪問您的配置:

Configuration["company_name"]

如果您有大量配置參數,則通過訪問初始化程序文件中的配置參數來預加載緩存可能會有所幫助。 如果您有1000個配置變量,則可能必須考慮將緩存遷移到memcached等。

如果要以類方法訪問配置參數:

class Configuration  < ActiveRecord::Base

 klass = class << self; self; end
 Configuration.all.each{|c| klass.send(:define_method, c.variable_name){c.value}}

end

現在,您可以按以下方式訪問參數:

Configuration.company_name

您在這里弄錯的一件事,永遠不會是Configuration.company_name ,就像訪問Class屬性而不是Object / Instance屬性,

它應該是配置類的實例。 在另一個答案中使用@KandagaBoggu的方法仍然可以接受,但是幾乎每次都可以訪問數據庫,也可以從Active Record的查詢緩存中訪問數據庫。但是AR的查詢緩存在特定操作(例如request)期間有效。 您可能想要使用類似Memcached的對象來使對象生存更長的時間。

當服務器啟動時,我們可以將這些常量值移到yml文件中,並將它們加載到變量中,並在需要時訪問它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM