我有一个名为Stack的模型,它是后台工作人员要完成的任务的列表.到目前为止,它只有一个后台工作人员做这项工作,但随着时间的推移,它变得有点臃肿,有点慢,堆栈是...好的,堆积起来.

就这个问题而言,假设这就是模型.

class Stack < ApplicationRecord
  enum state: { queued: 0, processing: 1, third_state: 2, fourth_state: 3 }
  validates :state, :object_name, :object_id, presence: true
end

因此,Stack有一款stateobject_name和一款object_id正在研发中.

在我们的数据库中,我们有以下Stack条目;

{ id: 1, state: :processing, object_name: "Car", object_id: 1 }
{ id: 2, state: :queued, object_name: "Car", object_id: 1 }
{ id: 6, state: :queued, object_name: "Car", object_id: 2 }
{ id: 7, state: :queued, object_name: "Truck", object_id: 2 }

我希望能够将上面的id:6作为下一个"队列",因为从理论上讲,另一个Worker已经在处理id:1,而我们不希望它拉出id:2,因为任务的主题与当前正在处理的id:1具有相同的对象名称和对象ID.

那么,如何获取堆栈中的下一个正在排队的对象,而不是如果它的对象在堆栈中的其他位置被处理呢?

我觉得我应该能够做一些事情,比如;

Stack.with_state(:queued).where.not("object_id = ? and object_name = ?", 
Stack.without_state(:queued).pluck(:object_id, :object_name).uniq ).to_sql

但这是行不通的,因为"对象id=?和对象名称=?"需要两个参数,因为我输入的查询给出了一个具有两个元素的数组array.

有什么 idea 吗?

推荐答案

如果我理解正确的话,您想要找到:

第一堆栈(按ID排序)处于"排队"状态,对于该状态,不存在与相同的object_nameobject_id相同的、不处于"排队"状态的其他堆栈.

如果是这样的话,以下方法应该适用于您:

stack_tbl = Arel::Table.new(Stack.table_name,as: 's2')

Stack
  .where(state: :queued)
  .where.not(
    stack_tbl
      .project(stack_tbl[Arel.star])
      .where(
        stack_tbl[:object_id].eq(Stack.arel_tbl[:object_id])
        .and(stack_tbl[:object_name].eq(Stack.arel_table[:object_name]))
        .and(stack_tbl[:state].not_eq(Stack.states[:queued]))
      ).exists
  )
 .order(:id)
 .limit(1)

这应该会产生以下SQL:

SELECT 
  stacks.*
FROM 
  stacks 
WHERE 
  stacks.state = 0 AND
  NOT EXISTS (
   SELECT 
     s2.* 
   FROM stacks s2 
   WHERE 
     s2.object_id = stacks.object_id 
     AND s2.object_name = stacks.object_name
     AND s2.state <> 0
)
ORDER BY
  stacks.id
LIMIT 1 

Ruby-on-rails相关问答推荐

Trailblazor 操作 -> 集合 :attribute(has_many 通过关联) 与填充器 -> 如何填充 Reform::Form 形式的 slugs 数组?

Ruby on Rails - 外键不匹配

升级到 Rails 6.1.6.1 导致 Psych::DisallowedClass: 试图加载未指定的类:符号

Rails 控制台 - 更新 Gem 后的弃用通知

Devise + Omniauth - 如何传递额外的参数?

如何在 Rails 中使用延迟作业(job)取消预定作业(job)?

如何在 Rails 中使用 instance_eval 子句删除验证?

Rails 4 Form: has_many through: checkboxes

Ruby 元素是否存在于数组中

Rails - 使用 %W

在 where 查询中查找 nil has_one 关联

在 ruby​​ 中构建公钥时,是什么导致既不是 PUB key 也不是 PRIV key::nested asn1 错误?

使用 AJAX 向 Rails 发送 Authenticity Token 的正确方法

在 rails 3 中批量插入

Post.all.map(&:id) 是什么意思?

在范围内传递参数

如何更改 Rails 3 控制器中视图文件的默认路径?

从模型中获取验证

如何拆分长行的 Ruby

Ruby 中的类别名