【问题标题】:Logic of interaction among models in Ruby on Rails?Ruby on Rails 中模型之间的交互逻辑?
【发布时间】:2013-03-25 02:35:32
【问题描述】:

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

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

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

也许有一些好的实践来组织或重构它?也许是 最好为此类交互创建一个通用模块,甚至创建 method_missing 使用通用方法的逻辑 put_, remove_, check_,如 warehouse.put_parcelwarehouse.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

仓库.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

【问题讨论】:

    标签: ruby-on-rails ruby design-patterns refactoring models


    【解决方案1】:

    怎么样

    warehouse.parcels.sum(:weight)
    

    这样您就可以根据当前数据运行“实时”查询,而不是递增。

    也是您当前模型的更简洁的版本:

      def set_current_weight
        @wh = self.warehouse
        @wh.current_weight += self.weight
        @wh.save
      end
    

    【讨论】:

    • 谢谢!那么,这个“实时”查询应该在包裹模型中的包裹保存或更新之后调用吗?或者最好在仓库模型中实现它?如果仓库里有100500个包裹怎么办? SQL 不是很重吗?
    • 就我个人而言,只要我想知道当前的重量,我就会运行查询。即使对于 100,000 行,SUM 命令也不是特别“繁重”,尤其是当您不进行任何其他数据操作时。澄清一下,我并不是说将其定义为任何模型中的方法,底层逻辑是内置在 ActiveRecord 中的。
    【解决方案2】:

    仓库的current_weight 实际上不是Parcel 对象授权的一部分。你也给了它不止一个改变的理由。因此,这打破了single responsibility principle

    我建议完全删除 :current_weightset_current_weight。像这样获取仓库内的总重量:

    def Warehouse < ActiveRecord::Base
      has_many :parcels
      # ...
    
      def current_weight
        parcels.sum(:weight)
      end
    end
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      相关资源
      最近更新 更多