2011-10-21 43 views
2

是否有任何內置方式將實例變量附加到記錄?例如,假設我有一個User類與fooattr_accessor用於記錄的Rails實例變量

class User < ActiveRecord::Base 
    ... 
    attr_accessor :foo 
end 

如果我做

u = User.first 
u.foo = "bar" 
u.foo # -> "bar" 
User.find(1).foo # => nil 

這是正確的行爲,我明白了爲什麼:實例變量存在的例如 (在內存中)而不是用於記錄。我想要的是類似於記錄變量,因此在上面的示例中,u.fooUser.find(1).foo在我的應用程序的同一實例內返回相同的值。我不想持久化:foo不適用於表中的列,它適合於foo在例如控制器操作,控制檯會話等生命週期中爲同一記錄返回相同的值。我也不希望通過cattr_accessor得到類變量,因爲沒有理由User.find(1).foo應該與User.find(2).foo相同。

我能想出的最好的辦法是用一個類變量數組和實例的方法來獲取假的/設置數組的適當元素:

class User < ActiveRecord::Base 

    cattr_accessor :all_the_foos 
    self.all_the_foos = Array.new 

    def foo 
    self.all_the_foos[id] 
    end 

    def foo= new_foo 
    self.all_the_foos[id] = new_foo 
    end 

end 

這種近乎工作,但它不」 t與未保存的記錄一起工作,例如User.new.foo = "bar"失敗。

+0

我想這很難回答這個問題,不知道你想存儲什麼樣的價值。你說你「不想要持久性」,但它聽起來像你希望實例從一個請求/會話/周保持相同的值到下一個,這就是「持久性」的定義。你能給我們更多的線索嗎? –

+0

該值將是另一個類的實例。我想要在常規實例變量和類變量的持續時間之間保持一段時間。因此,例如,如果我通過控制器操作觸發了一系列操作,則該值將保持一致,但操作完成後無需保留其值。這不是一個控制器變量,這只是一個例子。我寧願不進入具體情況b/c它是相對複雜的。我相當確信,我所問的問題正是我需要知道的。 – dantswain

回答

2

您可以使用Thread.current將制定是一個控制器操作調用的範圍內活動變量。您當前的實施不保證跨呼叫的上下文重置。

class User < ActiveRecord::Base 

    after_create :set_thread_var 

    def foo 
    new_record? ? @foo : Thread.current["User-foo-#{id}"] 
    end 

    def foo=(val) 
    new_record? ? (@foo = val) : (Thread.current["User-foo-#{id}"] = val) 
    end 

private 

    def set_thread_var 
    Thread.current["User-foo-#{id}"] = @foo if defined?(@foo) 
    end 

end 
+0

+1和謝謝。不過,我不得不放棄'attr_accessor',否則我的'foo'和'foo ='方法被忽略。我需要閱讀'Thread.current'來真正理解生命是什麼,但是這確實解決了我的問題。 – dantswain

1

我想不出比你的類變量解決方案更好的想法。要解決您的「new」問題,我會使用after_initialize

class User < ActiveRecord::Base 
    after_initialize :init_foos 

    cattr_accessor :all_the_foos 

    def foo 
    self.all_the_foos[id] 
    end 

    def foo= new_foo 
    self.all_the_foos[id] = new_foo 
    end 

    private 
    def init_foos 
    @@all_the_foos ||= [] 
    end 
end 
+0

+1和謝謝。我使用了@ KandadaBoggu的解決方案,因爲它明確地是線程安全的,並且當您訪問User.last.foo(這是我的錯誤)時,它不會創建長度爲N的數組。 – dantswain