【问题标题】:Rails Methods that call themselves调用自身的 Rails 方法
【发布时间】:2016-01-30 09:37:47
【问题描述】:

在 Rails 中,有没有一种方法可以让我根据数据库中的更改自行调用方法?例如,假设我有两个类:ProductsOrders

订单有三个可能的枚举值:

    class Order < ActiveRecord::Base
      enum status: [:pending, :processing,:shipped]
      belongs_to :products
     end

我想批量处理Orders,所以当一个产品有 50 个订单时,我希望它设置与之关联的所有订单来处理。 Orders 默认为 :pending。要将订单更改为:processing,我会致电order.processing!。我可以在 Products 模型中编写一个方法,例如:

def process_orders
  if self.orders.count=50
  self.orders.each do |order|
  order.processing!
  end
end

问题是我必须调用process_orders 方法才能执行,有没有办法让它在产品有50 个订单后自动执行?

【问题讨论】:

    标签: ruby-on-rails methods enums model state


    【解决方案1】:

    这听起来像是使用Active Record Callback 的好机会。

    class Order < ActiveRecord::Base
      belongs_to :product
    
      after_save do
        product.process_orders if product.pending_threshold_met?
      end
    end
    
    class Product < ActiveRecord::Base
      has_many :orders
    
      def pending_threshold_met?
        orders.where(status: :pending).count >= 50
      end
    end
    

    【讨论】:

      【解决方案2】:

      我认为您可以使用update_all 一次更新所有订单的status 列,而不是逐个循环:

      self.orders.update_all(status: :processing)
      

      并将其包装在回调中。

      类似这样的:

        class Order < ActiveRecord::Base
          after_save do
            product.process_orders if product.has_fifty_pending_orders?
          end
      
          # rest of your model code
        end
      
        class Product < ActiveRecord::Base
          # rest of your model code
      
          def process_orders
            self.orders.update_all(status: :processing)
          end
      
          def has_fifty_pending_orders?
            self.orders.where(status: :pending).count >= 50
          end
        end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-12
        • 2016-06-10
        • 2012-07-10
        • 1970-01-01
        • 2016-03-03
        • 2017-10-22
        • 2014-06-01
        相关资源
        最近更新 更多