0

「Rails を使用したアジャイル Web 開発」の本に従って、製品の価格を LineItem にコピーしようとしています。LineItem のセッターをオーバーライドするのが適切な選択のようです。ただし、Rails ではよくあることですが、セッターが 2 つ生成されると、作業が簡単ではなくなります。

  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

あなたのモデルは最適ではありません

あなたが何をしようとしているのか、なぜそうしようとしているのかはよくわかりませんが、問題の少なくとも一部は、モデルの関係が間違っているか、少なくとも最適ではないことにあるようです.

このように見てください:

  1. 製品には価格が必要です。これは論理的に製品のプロパティです。
  2. LineItem は、実際には Product とそのプロパティ、およびその他の関連データのプレゼンテーションです。

いくつかのチュートリアルに従っていることがわかりました。おそらく、チュートリアルは特定のポイントを作ろうとしているのでしょう。ただし、実際のアプリケーションでは、正規化されたデータベースがモデル間またはオブジェクト間でデータをコピーするべきではありません。価格は正確に 1 つの場所を持つ必要があり、他のテーブルから (コピーするのではなく) 参照する必要があります。

モデルに関する考慮事項

私のアドバイスに従えば、Product には ID があり、LineItem には product_id フィールドに格納された製品への参照があり、LineItem.product.price を介して価格にアクセスするか、または必要がない場合は委任を設定します。この一般的な使用例では、デメテルの法則に違反します。

これはチュートリアルの役に立たないかもしれませんが、ActiveRecord リレーションを使用することは、あるテーブルから別のテーブルに値をコピーするよりも確かに理にかなっています。YMMV。

于 2013-05-20T12:28:07.803 に答える