there is something that confuses me a little bit and i would like some clarification please, since it causes me some trouble.
I have a city model with a delegate to a wood_production attribute that specifies the amount of wood of that city. It’s like:
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
I normally wanted to be able to do a city.wood -= 1000 and save that value through the city, but i’ve come into all sorts of problems doings this. It seems that i am not setting my virtual attributes correctly maybe.
So i would actually like to ask, what is the difference between these :
def wood
self.wood_production_amount
end
def wood
wood_production_amount
end
def wood
self[:wood_production_amount]
end
and what should really be used to correctly handle the situation ?
EDIT :
If i create the setter like :
def wood= amt
self.wood_production_amount = amt
end
I get :
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 if the setter is :
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
Answering the first part,
self.wood_production_amountandwood_production_amountare functionally identical. The only difference is that in the latter, self is implied, being the current instance of the City model. I rarely use self.anything unless it’s required.self[:wood_production_amount]is functionally similar to the first two in most cases. The difference is that it allows you to easily overwrite default accessor methods.read_attribute(:attribute)is functionally identical toself[:attribute]. For example, say your City model has a state attribute, but you want to always return the state in uppercase when it is requested. You could do something like this:So to answer your second question, it really depends on how you want to use it. Personally, I would go with the delegate method unless you need to overwrite some behavior. The reason it wasn’t working for you might be that you aren’t delegating the setter method
:amount=as well: