2012-01-24 30 views
1

有些事情讓我有點困惑,我想請澄清一下,因爲這會導致我一些麻煩。與代表的虛擬屬性中的自我,自我[:項目]的差異

我有一個城市模型,帶有指定該城市木材數量的wood_production屬性的代理。這就像:

has_one :wood_production, :autosave => true 
delegate :amount, :to => :wood_production, :prefix => true, :allow_nil => true 

    def wood 
     wood_production_amount 
    end 

    def wood= amt 
     self[:wood_production_amount] = amt 
    end 

我通常希望能夠做一個city.wood - = 1000和保存價值穿城而過,但我接觸到的各種問題行爲這一點。看來,我可能沒有正確設置我的虛擬屬性。

所以,我真的想問,什麼是它們之間的區別:

def wood 
    self.wood_production_amount 
end 

def wood 
    wood_production_amount 
end 

def wood 
    self[:wood_production_amount] 
end 

,哪些應該被用於正確處理這種情況?

編輯:

如果我創建像二傳手:

def wood= amt 
    self.wood_production_amount = amt 
end 

我得到:

1.9.2p290 :003 > c.wood -= 1000 
=> 58195.895014789254 
1.9.2p290 :004 > c.save 
    (0.1ms) BEGIN 
    (0.3ms) UPDATE `wood_productions` SET `amount` = 58195.895014789254, `updated_at` = '2012-01-24 02:13:00' WHERE `wood_productions`.`id` = 1 
    (2.0ms) COMMIT 
=> true 

1.9.2p290 :005 > c.wood 
=> 66522.63434300483   ??????? 

BUF如果setter方法是:

def wood= amt 
    wood_production_amount = amt 
end 

1.9.2p290 :004 > c.wood -= 1000 
=> 58194.823000923556 
1.9.2p290 :005 > c.save 
    (0.1ms) BEGIN 
    (0.2ms) COMMIT 
=> true 

回答

2

回答第一個部分,self.wood_production_amountwood_production_amount在功能上是相同的。唯一的區別是在後者中,隱含着自我,即城市模型的當前實例。除非需要,否則我很少使用self.anything。

self[:wood_production_amount]在功能上是類似在大多數情況下是前兩種。區別在於它允許您輕鬆地覆蓋默認的訪問器方法。 read_attribute(:attribute)在功能上與self[:attribute]相同。例如,假設你的城市模型有一個狀態屬性,但是你希望當它被請求時總是以大寫字母返回狀態。你可以這樣做:

class City < ActiveRecord::Base 
    def state 
    self[:state].try(:upcase) 
    # or 
    read_attribute(:state).try(:upcase) 
    end 
end 

city = City.new(:state => 'vermont') 
city.state # => VERMONT 

所以要回答你的第二個問題,這真的取決於你想如何使用它。就個人而言,除非需要覆蓋某些行爲,否則我會使用委託方法。它不爲你工作的原因可能是,你是不是委託setter方法:amount=還有:

delegate :amount, :amount= :to => :wood_production, 
     :prefix => true, :allow_nil => true 
+0

很好的解釋感謝名單:)不過,即使設置委派的Setter後,這不保存新value:active_city.wood - = 1000 active_city.save(0.1ms)BEGIN (0.3ms)UPDATE'cities' SET'updated_at' ='2012-01-24 02:08:57'WHERE'cities'.'id' = 1 (44.1ms)COMMIT。任何想法爲什麼?我編輯我的問題來說明 – Spyros

+0

你有一個setter方法'wood =(value)'? –

+0

是的,這是我的問題的第一部分代碼。我嘗試了所有版本,似乎都沒有工作:/ – Spyros