0

私はRailsを研究していて、モデル間の相互作用を整理しようとしています。私が書いたものは機能しますが、コードの臭いは悪いと思います。

たとえば、データベーステーブルParcelと。を持つ2つのモデルがありますWarehouse:current_weight新しいパーセルを作成するときに、この新しいパーセルに関連するWarehouseインスタンスのを増やしたいと思います。

繰り返しになりますが、すべてが機能しますが、このタイプのコード、つまり2つの異なるオブジェクト間の相互作用は頻繁に使用され、私の心の奥底にある何かが「おい、このコードはひどくて、将来問題を引き起こすでしょう!」と言います。

多分それを整理またはリファクタリングするためのいくつかの良い習慣がありますか?たぶん、そのような相互作用のためのユニバーサルモジュールを作成するか、ユニバーサル、、、、 like および。でmethod_missingメソッドを使用するロジックを作成する方が良いでしょう。put_remove_check_warehouse.put_parcelwarehouse.remove_parcel

ルビーコンソールの場合:

parcel = Parcel.new
parcel.weight = 10
parcel.warehouse_id = 1
parcel.save

# Create parcel and increase :current_weight of related warehouse by 10 after save

Warehouse.rb:

class Warehouse < ActiveRecord::Base
    has_many :parcels
  attr_accessible :name, :current_weight
end

parcel.rb:

class Parcel < ActiveRecord::Base
    belongs_to :warehouse
    belongs_to :vehicle
  attr_accessible :name, :weight, :warehouse_id, :vehicle_id

  after_save :set_current_weight

  #Bad code:
  def set_current_weight
    @wh = self.warehouse
    @wh.current_weight = @wh.current_weight + self.weight
    @wh.save
  end
end
4

2 に答える 2

1

どうですか

warehouse.parcels.sum(:weight)

このようにして、増分ではなく、現在のデータに基づいて「ライブ」クエリを実行します。

現在のモデルのもう少し簡潔なバージョンも:

  def set_current_weight
    @wh = self.warehouse
    @wh.current_weight += self.weight
    @wh.save
  end
于 2013-03-25T02:59:28.517 に答える
0

current_weight倉庫のは、実際にはParcelオブジェクトの義務の一部ではありません。また、変更する理由は複数あります。したがって、これは単一責任の原則に違反します。

:current_weight削除してset_current_weight完全に削除することをお勧めします。次のように倉庫内の総重量を取得します。

def Warehouse < ActiveRecord::Base
  has_many :parcels
  # ...

  def current_weight
    parcels.sum(:weight)
  end
end

@muttonlambが彼の投稿で示唆しているように。

于 2013-03-25T03:34:19.477 に答える