我正在关注“使用Rails进行敏捷Web开发”一书并尝试将产品价格复制到LineItem。在LineItem上覆盖setter似乎是合适的选择。但是,正如在Rails中经常出现的那样,有两个生成的setter使得练习变得非常重要:
def product_id=(product_id)
product = Product.find(product_id)
write_attribute(:price, product.price)
write_attribute(:product_id, product_id)
end
def product=(product)
self.product_id = product.id #wtf? why isn't this the default?
end
此代码按预期工作,无论我是设置对象还是它的id,在这两种情况下都会复制价格。是什么让我想知道:
为什么这个代表不工作而不必覆盖“product =(..)”?奇怪的是,没有删除“自我”它将无法工作,显然它不会委托给“product_id =()”......
答案 0 :(得分:1)
使用默认实现调用product=
将不会调用product_id=
。它只是像您在重写的write_attribute
方法中那样使用product_id=
。
答案 1 :(得分:-1)
我不确定你要做什么,或者你为什么要这样做,但在我看来,至少你的部分问题是你的模型关系是错误的 - 或者至少次优的。
这样看:
我意识到你正在学习一些教程,所以也许本教程试图提出一些具体的观点。但是,在实际应用程序中,规范化数据库不应该从模型到模型或对象到对象复制数据;价格应该只有一个居住地,应该从其他表中引用(而不是复制)。
如果您遵循我的建议,则产品具有ID,LineItem具有对product_id字段中存储的产品的引用,您可以通过LineItem.product.price访问价格,或者如果您不知道,则设置委派我想违反这个常见用例的Demeter法。
这可能对您的教程没有帮助,但使用ActiveRecord关系对我来说比将值从一个表复制到另一个表更有意义。 YMMV。