Rails 调用自身的方法
Rails Methods that call themselves
在 Rails 中,有没有一种方法可以根据数据库中的更改自行调用方法?例如,假设我有两个 类:Products
和 Orders
。
订单具有三个可能的枚举值:
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 个订单后自动执行吗?
这听起来是使用 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
我认为您可以使用 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
在 Rails 中,有没有一种方法可以根据数据库中的更改自行调用方法?例如,假设我有两个 类:Products
和 Orders
。
订单具有三个可能的枚举值:
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 个订单后自动执行吗?
这听起来是使用 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
我认为您可以使用 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