3

可以說,在我的Rails應用程序的頂部有一個帶有一段文本的欄 - 最新的熱門交易,計劃的停機通知等等。這是一種單獨的信息,基本上每個請求都需要訪問,並且可能會不時更新。達到此目的的最佳方法是什麼?Rails中的永久變量

我想要做的是某種永久性全局變量(可從控制器訪問)。

  • 它很少被更新,因此如果在更新後的一段時間內工作人員之間會出現不一致的情況,則不會有任何問題。
  • 另一方面,它應該在服務器故障的情況下保持不變(週期性備份就足夠了)。
  • 它會經常被訪問,所以它應該儘可能快 - 最好留在內存中。
  • 此外,它只是一種,所以我真的不想用專用的數據庫模型來擴大應用程序。

這樣的事情在Node.js中很容易,但我找不到在Rails中實現這一點的單一方法。我該怎麼辦?

編輯

感謝您的答案,到目前爲止,但同時他們是鼓舞人心的,我認爲我應該強調了一個關鍵的功能,他們都不見了。 該變量應該可在應用程序內編輯並持久化。儘管可以編輯變量,但在服務器重新啓動的情況下,我又回到了默認值 - 這很糟糕。

回答

0

好的,這就是我所做的。我沒有將這個值賦給一個初始化器,而是創建了一個處理它的簡單類。變量本身存儲在一個預定義的文件中。除了在初始化時讀取文件之外,該類在更改值時更新文件,並且還定期重新讀取該文件以保持工作人員之間的一致性。我還提供了一些基本的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 
0

來源: 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 
1

你可以在初始化聲明爲一個常數作爲MYVARIABLE

+0

如果我以後改變了這個變量,它會在工人之間保持一致嗎? – 2012-02-28 23:39:29

+0

不,您可以使用dRuby在所有工作人員之間傳遞更新。 – rudolph9 2012-05-04 14:30:28

2

這真的取決於你在找什麼。你可以通過把它在你的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

0

我已經開始把常量和變量這樣的配置對象,例如

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

我會將它存儲在數據庫中並讓緩存來處理它。

我覺得在適當的時候,對於那些需要在許多地方共享這個公共值的代碼來說,全局變量是很好的,但這是代碼,而不是用戶視圖。
在這種情況下,顯然這是因爲OP粗體顯示爲'可由應用程序編輯'。所以我會有一個讓用戶輸入它的視圖,它存儲在一個數據庫表中,然後根據需要調用(如曾經使用過的緩存)。

2

嗯,我已經遇到了類似的問題。 我的問題是我需要所有級別(MVC)的全局變量。 我們去使用Memcache來存儲變量。 也許你可以去找一個類似的解決方案。 作爲額外的獎勵,您可以在整個程序中進行更改。