【问题标题】:Can this raw SQL be written using the Rails Active Record Query Interface? Should it be?可以使用 Rails 活动记录查询接口编写此原始 SQL 吗?应该是吗?
【发布时间】:2023-03-04 23:07:02
【问题描述】:

在我的 Rails 4 应用程序中,我使用以下 SQL 'OR' 语句对我的模型之一进行了相当简单的搜索。它工作正常。有什么方法(和理由)可以在没有使用 Rails Active Record 查询接口的原始 SQL 的情况下实现这一点?

Activity.where("
    user_id = ? OR 
    category = ? OR 
    (secondary_id = ? AND secondary_model = ?) OR 
    (tertiary_id = ? AND tertiary_model = ?)",
    user_id, "Announcement", user_id, "user", user_id, "user"
).uniq

【问题讨论】:

  • 如果还是这样的话,也许可以使用 Arel
  • 你试过ActiveRecord::Base.connection.execute 吗?它应该可以解决您的问题。
  • 你可以通过 AREL 来做,但我认为它不会更容易阅读。不过,切换到命名参数(user_id = :user_id or ... 参数带有哈希)是一个好主意,这将避免参数列表中的重复参数和顺序敏感性。
  • 添加一个group 子句以使数据库的唯一性成为工作也是值得的
  • @Pavling: uniq 是一个 ActiveRecord 方法。 GROUP BY 用于聚合,而不是唯一性,将其用于唯一性是一种滥用,仅适用于某些数据库。

标签: sql ruby-on-rails postgresql activerecord


【解决方案1】:

你可以在这里使用Arel。许多 Rails 查询在幕后使用 Arel,但您可以直接挂钩。

至于你是否应该,我认为这取决于项目。我们通常使用 Arel,因此如果我们更改 RDBM,它会为我们转换 SQL。我不认为它真的让它看起来好多了。

你的代码看起来像这样

activities = Activity.arel_table
activities
   .where(activities[:user_id].eq(user_id)
   .or(activities[:category].eq("Announcement")
   .or((activities[:secondary_id].eq("user").and(activities[:secondary_model].eq(user_id))
   .or((activities[:tertiary_id].eq("user").and(activities[:secondary_model].eq(user_id)))

【讨论】:

  • 我发现大多数 AREL 都是难以理解的混乱。我不了解可移植性方面,AREL 并没有真正涵盖可移植性的难点,是吗?对我来说,AREL 是用于以编程方式构建标准 AR 调用并不能真正做到的事情。如果 SQL 是静态的,那么 AREL 只会以某种扭曲的意识形态纯洁感的名义不必要地使事情复杂化。当然是国际海事组织。
  • 我对它还很陌生,所以我还没有强烈的意见。我同意在这种情况下,可移植性并不是真正的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多