0

我正在研究 Rails,现在正在尝试组织模型之间的交互。我写的东西很有效,但我认为代码闻起来很糟糕。

例如,我有两个带有数据库表的模型ParcelWarehouse. 当我创建一个新 Parcel 时,我想增加:current_weight与这个新 Parcel 相关的 Warehouse 实例的数量。

再次,一切正常,但是这种类型的代码,两个不同对象之间的交互,将被频繁使用,我内心深处的一句话是:“伙计,这个代码很糟糕,将来会引起问题!”。

也许有一些好的做法来组织或重构它?也许最好为这种交互创建一个通用模块,或者甚至创建 method_missing逻辑来使用具有universal put_, remove_, check_, like warehouse.put_parceland的方法warehouse.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

仓库.rb:

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

包裹.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_weightset_current_weight。像这样获取仓库内的总重量:

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

  def current_weight
    parcels.sum(:weight)
  end
end

正如@muttonlamb 在他的帖子中所建议的那样。

于 2013-03-25T03:34:19.477 回答