优化读取的一种方法是设置一个单独的外键列和关联作为最新执行的“快捷方式”:
class AddLatestExecutionToProducts < ActiveRecord::Migration[6.0]
def change
add_reference :latest_execution, :execution
end
end
class PeriodicJob < ApplicationRecord
has_many :executions,
after_add: :set_latest_execution
belongs_to :latest_execution,
optional: true,
class_name: 'Execution'
private
def set_latest_execution(execution)
update_attribute(:latest_execution_id, execution.id)
end
end
这使您可以执行PeriodicJob.eager_load(:latest_execution) 并避免 N+1 查询和从执行表中加载所有记录。如果每个周期作业有很多执行,这一点尤其重要。
成本是每次创建执行时都需要额外的写入查询。
如果您想将其限制为仅最新的成功/失败,您可以添加两列:
class AddLatestExecutionToProducts < ActiveRecord::Migration[6.0]
def change
add_reference :latest_successful_execution, :execution
add_reference :latest_failed_execution, :execution
end
end
class Execution < ApplicationRecord
enum state: {
succeeded: 'succeeded',
failed: 'failed'
}
end
class PeriodicJob < ApplicationRecord
has_many :executions,
after_add: :set_latest_execution
belongs_to :latest_successful_execution,
optional: true,
class_name: 'Execution'
belongs_to :latest_failed_execution,
optional: true,
class_name: 'Execution'
private
def set_latest_execution(execution)
if execution.succeeded?
update_attribute(:latest_successful_execution_id, execution.id)
else
update_attribute(:latest_failed_execution_id, execution.id)
end
end
end