有些东西让我感到困惑,我想请一些澄清,因为它给我带来了一些麻烦。
我有一个城市模型,其中包含一个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
应该用什么才能正确处理这种情况?
编辑:
如果我创建了这样的setter:
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 ???????
如果设置者是:
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
答案 0 :(得分:2)
回答第一部分self.wood_production_amount
和wood_production_amount
功能相同。唯一的区别是,在后者中,自我是隐含的,是城市模型的当前实例。我很少使用self.anything,除非它是必需的。
self[:wood_production_amount]
在功能上与前两个类似。不同之处在于它允许您轻松覆盖默认的访问器方法。 read_attribute(:attribute)
在功能上与self[:attribute]
相同。例如,假设您的City模型具有state属性,但您希望在请求时始终以大写形式返回状态。你可以这样做:
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