我正在研究Rails,现在正试图组织模型之间的互动。我写的东西有效,但我认为代码闻起来很糟糕。
例如,我有两个包含数据库表Parcel
和Warehouse
的模型。当我创建一个新的包时,我想增加与这个新包相关的Warehouse实例的:current_weight
。
同样,一切都有效,但是这种类型的代码,两个不同对象之间的交互,将经常被使用,而我脑海中的一些内容则说:“老兄,这段代码很糟糕,将来会引发问题!”。
也许有一些好的做法可以组织或重构它?也许是的
更好地为这种交互创建通用模块,甚至创建
使用通用method_missing
,put_
方法的remove_
逻辑,
check_
,例如warehouse.put_parcel
和warehouse.remove_parcel
。
在ruby控制台中:
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
答案 0 :(得分:1)
怎么样
warehouse.parcels.sum(:weight)
这样您就可以根据当前数据运行“实时”查询,而不是递增。
您当前型号稍微简洁一点:
def set_current_weight
@wh = self.warehouse
@wh.current_weight += self.weight
@wh.save
end
答案 1 :(得分:0)
仓库的current_weight
实际上不属于Parcel
对象任务的一部分。你也给了它不止一个改变的理由。因此,这打破了single responsibility principle。
我建议完全删除:current_weight
和set_current_weight
。像这样得到仓库内的总重量:
def Warehouse < ActiveRecord::Base
has_many :parcels
# ...
def current_weight
parcels.sum(:weight)
end
end
正如@muttonlamb在他的帖子中所建议的那样。