gpt4 book ai didi

ruby-on-rails - Ruby:将 Arel.sql 转换为 Arel::Nodes::Case 的想法?

转载 作者:行者123 更新时间:2023-12-05 06:07:21 24 4
gpt4 key购买 nike

我正在尝试重构一段代码(并提高我对 Arel::Nodes::Case 的理解),我想转换此 Arel.sql 语句

    Arel.sql(default_order)
def default_order
"CASE
WHEN applications.status = 'new' AND owner_id IS NULL THEN '1'
WHEN applications.is_priority = '1' AND is_read = '0' AND owner_id = '#{current_user.id}' THEN '2'
WHEN applications.is_priority = '1' THEN '3'
ELSE '4'
END, applications.code"
end

进入 Arel::Nodes::Case 但我没有得到任何好的结果。有什么有用的想法吗?

非常感谢。

更新

我采用了这种方法,但我一点也不喜欢它。太难阅读和理解:

  def default_order
arel_applications = Application.arel_table
Arel::Nodes::Case.new
.when((arel_applications[:status].eq('new'))
.and(arel_applications[:owner_id].eq(nil)), 1)
.when((arel_applications[:is_priority].eq(1))
.and(arel_applications[:is_read].eq(0))
.and(arel_applications[:owner_id].eq(current_user.id)), 2)
.when(arel_applications[:is_priority].eq(1), 3)
.else(4).to_sql
end

即便如此,我还是不确定如何获取 SQL 中用于对记录进行排序的 applications.code

最佳答案

你不能总是期望 Arel 很漂亮。 Arel 是一个非常复杂和灵活的查询汇编器,这种复杂性的副作用通常是冗长。

也就是说,在我看来,使用 Arel 而不是原始 sql 总是优先的,因为它卫生、动态且与数据库无关。

我们可以通过使用 then 方法而不是 when 的第二个参数来改变您的更新,使其更具可读性。这将使代码读起来更像 CASE 语句,例如 .when(condition).then(value)

改变看起来像这样:

  def default_order
arel_applications = Application.arel_table
case_stmnt = Arel::Nodes::Case.new
.when(arel_applications[:status].eq('new').and(
arel_applications[:owner_id].eq(nil)
)
).then(1)
.when(arel_applications[:is_priority].eq(1).and(
arel_applications[:is_read].eq(0).and(
arel_applications[:owner_id].eq(current_user.id)
)
)
).then(2)
.when(arel_applications[:is_priority].eq(1)
).then(3)
.else(4)
end

现在处理问题的第二部分“即便如此,我不确定如何获取 SQL 中使用的 applications.code 来对记录进行排序。”

我们可以使用 Arel::Nodes::Grouping 来处理这个问题:

def default_order
arel_applications = Application.arel_table
case_stmnt = Arel::Nodes::Case.new
.when(arel_applications[:status].eq('new').and(
arel_applications[:owner_id].eq(nil)
)
).then(1).
.when(arel_applications[:is_priority].eq(1).and(
arel_applications[:is_read].eq(0).and(
arel_applications[:owner_id].eq(current_user.id)
)
)
).then(2)
.when(arel_applications[:is_priority].eq(1)
).then(3)
.else(4)
Arel::Nodes::Grouping.new(case_stmnt,arel_applications[:code])
end

这将导致以下 SQL:

(CASE 
WHEN [applications].[status] = N'new' AND [applications].[owner_id] IS NULL THEN 1
WHEN [applications].[is_priority] = 1 AND [applications].[is_read] = 0 AND [applications].[owner_id] = 1 THEN 2
WHEN [applications].[is_priority] = 1 THEN 3
ELSE 4 END,
[applications].[code])

然后您可以将其用作 order 的参数(无需将 转换为_sql,因为 rails 会为您处理此问题,例如 Application.order (默认顺序)

您还可以将排序方向附加到 case_stmntarel_applications[:code] 列,例如case_stmnt.asccase_stmnt.desc

关于ruby-on-rails - Ruby:将 Arel.sql 转换为 Arel::Nodes::Case 的想法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65477244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com