根据 Postgres/Ruby 在 Rails 中的优先级自动将对象分配给用户
Auto-assigning objects to users based on priority in Postgres/Ruby on Rails
我正在构建一个 rails 应用程序来管理工作项队列。我有几种类型的用户 ("access levels"),我想将这些工作项自动分配给他们。
最终目标是我的其中一个视图上的 "Auto-assign" 按钮,它会根据优先级自动获取下一个工作项目,该优先级由用户的访问级别定义。
我正在尝试在我的 work_item 模型中设置一个 class 方法,以根据用户的访问级别自动按类型对工作项进行排序。我正在看这样的东西:
def self.auto_assign_next(access_level)
case
when access_level = 2
where("completed = 'f'").order("requested_time ASC").limit(1)
when access_level > 2
where("completed = 'f'").order("CASE WHEN form='supervisor' THEN 1 WHEN form='installer' THEN 2 WHEN form='repair' THEN 3 WHEN form='mail' THEN 4 WHEN form='hp' THEN 5 ELSE 6 END").limit(1)
end
虽然这不是很干。理想情况下,我希望管理员可以配置排序顺序,因此最好设置一个单独的 table 来保留排序顺序。这个想法的问题是我不知道如何将 table 的优先顺序传递给 [postgre]SQL 查询。总的来说,我是 SQL 的新手,对此有些迷茫。有人对如何处理这件事有什么建议吗?
一个相当简单的方法首先是将您的案例语句变成一个新的 table,列出 form
值与它们应该排序的 precedence
值:
id | form | precedence
-----------------------------------
1 | supervisor | 1
2 | installer | 2
(etc)
为此创建一个模型,比如说,FormPrecedences
(不是一个好名字,但我并不完全理解你的数据模型,所以选择一个能更好地描述它的模型)。然后,您的查询可能如下所示(注意:我假设您当前的模型称为 WorkItems):
when access_level > 2
joins("LEFT JOIN form_precedences ON form_precedences.form = work_items.form")
.where("completed = 'f'")
.order("COALESCE(form_precedences.precedence, 6)")
.limit(1)
它的工作方式并不像看起来那么复杂。 SQL 中的 "left join" 简单地获取左侧 table 的所有行(在本例中为 work_items
),并且对于每一行,从中找到所有匹配的行右侧的 table(form_precedences
,其中 "matching" 由 "ON" 关键字后的位定义:form_precedences.form = work_items.form
),并发出一个组合行。如果未找到匹配项,LEFT JOIN
仍会发出一行,但所有右侧的值为 NULL。普通连接会跳过没有找到右手匹配项的任何行。
无论如何,将优先级数据加入到我们的工作项中,我们可以按优先级值排序。但是,如果在上面的连接期间未找到匹配项,则该值将为 NULL——因此,我使用 COALESCE
(returns 它的第一个不为 NULL 的参数)默认为优先级6
.
希望对您有所帮助!
我正在构建一个 rails 应用程序来管理工作项队列。我有几种类型的用户 ("access levels"),我想将这些工作项自动分配给他们。
最终目标是我的其中一个视图上的 "Auto-assign" 按钮,它会根据优先级自动获取下一个工作项目,该优先级由用户的访问级别定义。
我正在尝试在我的 work_item 模型中设置一个 class 方法,以根据用户的访问级别自动按类型对工作项进行排序。我正在看这样的东西:
def self.auto_assign_next(access_level)
case
when access_level = 2
where("completed = 'f'").order("requested_time ASC").limit(1)
when access_level > 2
where("completed = 'f'").order("CASE WHEN form='supervisor' THEN 1 WHEN form='installer' THEN 2 WHEN form='repair' THEN 3 WHEN form='mail' THEN 4 WHEN form='hp' THEN 5 ELSE 6 END").limit(1)
end
虽然这不是很干。理想情况下,我希望管理员可以配置排序顺序,因此最好设置一个单独的 table 来保留排序顺序。这个想法的问题是我不知道如何将 table 的优先顺序传递给 [postgre]SQL 查询。总的来说,我是 SQL 的新手,对此有些迷茫。有人对如何处理这件事有什么建议吗?
一个相当简单的方法首先是将您的案例语句变成一个新的 table,列出 form
值与它们应该排序的 precedence
值:
id | form | precedence
-----------------------------------
1 | supervisor | 1
2 | installer | 2
(etc)
为此创建一个模型,比如说,FormPrecedences
(不是一个好名字,但我并不完全理解你的数据模型,所以选择一个能更好地描述它的模型)。然后,您的查询可能如下所示(注意:我假设您当前的模型称为 WorkItems):
when access_level > 2
joins("LEFT JOIN form_precedences ON form_precedences.form = work_items.form")
.where("completed = 'f'")
.order("COALESCE(form_precedences.precedence, 6)")
.limit(1)
它的工作方式并不像看起来那么复杂。 SQL 中的 "left join" 简单地获取左侧 table 的所有行(在本例中为 work_items
),并且对于每一行,从中找到所有匹配的行右侧的 table(form_precedences
,其中 "matching" 由 "ON" 关键字后的位定义:form_precedences.form = work_items.form
),并发出一个组合行。如果未找到匹配项,LEFT JOIN
仍会发出一行,但所有右侧的值为 NULL。普通连接会跳过没有找到右手匹配项的任何行。
无论如何,将优先级数据加入到我们的工作项中,我们可以按优先级值排序。但是,如果在上面的连接期间未找到匹配项,则该值将为 NULL——因此,我使用 COALESCE
(returns 它的第一个不为 NULL 的参数)默认为优先级6
.
希望对您有所帮助!