2011-10-06 27 views
2

我有一個Rails 3應用程序,並正在執行配置文件完整性某種功能。當用戶登錄時,應用程序應該向他/她展示製作「完整」配置文件的進度。爲了說明我正在使用在應用程序初始化時填充了需求的單例類。單例有一個數組@requirements。它使用我的初始化程序正確填充。當我點擊ProfileController時,顯示需求。但是,在第一個分支請求ProfileController#completeness列表否@requirements。單例中的數組是空的。我相信單身人士不會在控制器請求中返回相同的實例。我在哪裏錯了?跨控制器的Rails單身對象清除

注意:這個類只是持有要求,而不是特定用戶在實現它們方面的進展。需求很少改變,所以我想避免數據庫查找。

# lib/profile_completeness.rb 
require 'singleton' 

class ProfileCompleteness 

    include Singleton 
    include Enumerable 

    attr_reader :requirements 

    def add_requirement(args) 
    b = Requirement.new(args) 
    @requirements << b 
    b 
    end 


    def clear 
    @requirements = [] 
    end 


    def each(&block) 
    @requirements.each { |r| block.call(r) } 
    end 


    class Requirement 
    # stuff 
    end 

end 

-

# config/initializers/profile_completeness.rb 
collection = ProfileCompleteness.instance() 
collection.clear 

collection.add_requirement({ :attr_name => "facebook_profiles", 
          :count => 1, 
          :model_name => "User", 
          :instructions => "Add a Facebook profile" }) 

-

class ProfileController < ApplicationController 
    def completeness 
    @requirements = ProfileCompleteness.instance 
    end 

end 

-

<!-- app/views/profile/completeness.html.erb --> 
<h2>Your Profile Progress</h2> 
<table> 
    <%- @requirements.each do |requirement| 
     complete_class = requirement.is_fulfilled_for?(current_user) ? "complete" : "incomplete" -%> 

    <tr class="profile_requirement <%= complete_class -%>"> 

     <td> 
     <%- if requirement.is_fulfilled_for?(current_user) -%> 
      &#10003; 
     <%- end -%> 
     </td> 

     <td><%= raw requirement.instructions %></td> 

    </tr> 
    <%- end -%> 
</table> 
<p><%= link_to "Profile", profile_path -%></p> 

回答

2

這是不行的(多線程,不同的rails工作人員等),你不能指望在每個請求登陸相同的rails應用程序線程。如果您的服務器崩潰,所有進度都會丟失!因此,跨請求/會話永久保存數據的方式就是數據庫。

將完整性跟蹤器建模爲模型並將其存儲在數據庫中。

另一個解決方案是使用Rails應用程序緩存。

設置一個鍵/值對:

Rails.cache.write('mykey', 'myvalue'); 

閱讀:

cached_value = Rails.cache.read('mykey'); 

Read more about Rails Cache

如果你想爲大數據集和快速訪問的解決方案,我建議你使用redis:

Here is a good article尤其是sec 「使用Redis作爲Rails緩存存儲」並查看「Redis相關的寶石」部分。

重要的是鍵/值數據結構,我會去鍵,如

progress:user_id:requirements = [{ ...requirement 1 hash...}, {..requirement 2 hash.. }] 
+0

ProfileComplete類只保存需求,而不是特定用戶的進度。向班級詢問用戶完成多少要求是很容易的。需求很少會改變,所以我想保存一個數據庫查詢。 –

+0

看到我的編輯;) – sled

+0

是的,這將做。 –

1

,因爲這些被隔離到單個進程不能在Rails的環境中使用單身的其中可能會有很多,而且很糟糕她和開發模式一樣,這些類在每次請求時都會故意重新初始化。

這就是爲什麼你看到任何保存在它們中的東西消失。

如果您必須在請求之間保持這樣的數據,請使用session工具。

一般的想法是創建一些你可以通過這裏引用的持久記錄,比如創建一個表來存儲ProfileComplete的記錄。然後,您可以在每個請求中重新加載此請求,根據需要進行更新並保存更改。

+0

我想避免訪問數據庫。將會有一些幾乎不會改變的要求。我認爲會議適合個人的要求。我想在整個應用程序的內存中收集一個集合。 –

+0

只要查詢很快,我就不會害怕旅行到數據庫。沒人會注意到加載延遲1ms。 – tadman