0

我正在关注“Agile Web Development with Rails”一书并尝试将产品价格复制到 LineItem。覆盖 LineItem 上的设置器似乎是合适的选择。然而,正如在 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=(..)”?奇怪的是,如果不删除“self”,它将无法正常工作,显然它不会委托给“product_id =()”......

4

2 回答 2

1

使用默认实现调用product=不会调用product_id=. 它write_attribute就像您在覆盖product_id=方法中所做的那样简单地使用。

于 2013-05-20T16:20:01.250 回答
-1

你的模型不是最优的

我不确定您要做什么,或者您为什么要这样做,但在我看来,您的问题至少有一部分是您的模型关系是错误的——或者至少是次优的.

这样看:

  1. 产品应该有价格。这在逻辑上是产品的属性。
  2. LineItem 实际上是Product 及其属性的表示,可能还有其他一些相关数据。

我意识到你正在关注一些教程,所以也许教程试图提出一些具体的观点。但是,在现实世界的应用程序中,规范化数据库不应该从模型到模型或对象到对象复制数据。价格应该只有一个住处,并且应该从其他表中引用(而不是复制)。

模型注意事项

如果你听从我的建议,那么 Product 有一个 ID,LineItem 有对存储在 product_id 字段中的产品的引用,你可以通过 LineItem.product.price 访问价格,或者如果你不想设置委托这个常见用例违反了得墨忒耳定律。

这可能对您的教程没有帮助,但对我来说,使用 ActiveRecord 关系肯定比将值从一个表复制到另一个表更有意义。YMMV。

于 2013-05-20T12:28:07.803 回答