需要帮助重新编写一些最初使用名为 Squeel 的 gem 编写的 Rails DB 查询,具有有效的 SQL

Posted

技术标签:

【中文标题】需要帮助重新编写一些最初使用名为 Squeel 的 gem 编写的 Rails DB 查询,具有有效的 SQL【英文标题】:Need assistance re-writing some Rails DB Queries that were originally written with a gem called Squeel, have the working SQL 【发布时间】:2021-11-20 21:58:07 【问题描述】:

我有几个非常困难的数据库查询,我需要帮助才能以正确的方式为 Rails 6 Active Record 重写。这些目前正在一个应用程序中工作,我正在重写新版本的 Ruby on Rails (6.1.4.2)。

它最初是在 Rails v3.2 上编写的,带有一个名为 squeel 的地狱 gem,它使用自己的 DSL 语言。

https://github.com/activerecord-hackery/squeel

我已经尝试了几天,但无法弄清楚。我第一次问它时,我可能没有我需要的那么清楚。所以这次我将把查询放在 squeel 中写的那样,以及 Heroku 控制台吐出的 SQL,仅此而已。如果有人想要任何其他信息,请询问,我会很乐意发布。我想保持简单,因为它们足够令人困惑。

警告:这些似乎非常复杂。 任何帮助将不胜感激! :)

这里是 squeel DB 查询 1:

Project.joinsvendor.joinscertifications.outer.where
        (projects.vendor_id.eq my vendor_id ) |
        (vendors.parent_vendor_id.eq my vendor_id ) |
        ((certifications.cdti == true) & (certifications.published == true))
      .uniq

这是来自 Rails v3.2 的查询 1 的海峡 SQL:

SELECT DISTINCT "vendors".* FROM "vendors" INNER JOIN "projects" ON "projects"."vendor_id" = "vendors"."id" 
INNER JOIN "certifications" ON "certifications"."project_id" = "projects"."id" 
WHERE (("certifications"."cdti" = 't' AND "certifications"."published" = 't')) 
ORDER BY "vendors"."parent_vendor_id", "vendors"."name"

这里是 squeel DB 查询 2:

Fleet.joinsvendor.projects.certifications.
        where(certifications.cdti.eq true) & (certifications.published.eq true).
        uniq.includes(:vendor).
        order(:vendor_id, :name)

这是来自 Rails v3.2 的查询 2 的海峡 SQL: (我在几个地方按了 Enter,这样您就可以看到整个语句而无需向右滚动

SELECT DISTINCT "fleets".* FROM "fleets" INNER JOIN "vendors" ON "vendors"."id" = "fleets"."vendor_id" 
INNER JOIN "projects" ON "projects"."vendor_id" = "vendors"."id" 
INNER JOIN "certifications" ON "certifications"."project_id" = "projects"."id" 
WHERE (("certifications"."cdti" = 't' AND "certifications"."published" = 't')) 
ORDER BY "fleets"."vendor_id", "fleets"."name"

再次,如果有人想查看或了解其他任何内容,请告诉我,因为我正在尽力解决这个问题,但这些看起来太先进了,我只是不认为我知道正确的语法。

感谢您的宝贵时间, 斯科特

【问题讨论】:

根据你的 SQL,我猜查询 1 是:Vendor.joins(projects: :certifications).where(certifications: cdti: 't', published: 't' ).order(:parent_vendor_id, :name).distinct。你能检查一下是否生成了正确的 SQL 查询吗? 另外,查询 2 可能等同于:Fleet.joins(vendors: projects: :certifications ).where(certifications: cdti: 't', published: 't' ).order(:vendor_id, :name).distinct。让我知道他们是否有帮助。如果是这样,我会写答案 @JoãoFernandes,我收到一个错误:ActiveRecord::ConfigurationError at /projects 无法将“舰队”加入名为“供应商”的关联;也许你拼错了? 我一直在尝试将 JUST Fleets 加入供应商,但我什至无法让这两个工作。如果您需要查看关联的 3 个模型,请告诉我。我相信查询 1 有效,据我所知,它已经过去了。 FleetVendorhas_one 关联?如果是这样,您可能必须从 vendors: 更改为 vendor 【参考方案1】:

查询 1 等效项是:

Vendor.joins(projects: :certifications).where(certifications:  cdti: 't', published: 't' ).order(:parent_vendor_id, :name).distinct

查询 2:

Fleet.joins(vendor:  projects: :certifications ).where(certifications:  cdti: 't', published: 't' ).order(:vendor_id, :name).distinct

【讨论】:

我不明白,如果它使用 has_one / belongs_to 关联,您必须使用:vendor,vs :vendorS。沉重的教训,我不会忘记的。 :) 那个小 S 花了我很多时间!再次感谢@João Fernandes 我之前以不同的方式发布了这个问题,如果你想回答这个问题,这基本上是相同的答案。否则,当我让它们正确并正常工作时,我会写下答案,但没有你,我无法做到。 ***.com/questions/69272014/…

以上是关于需要帮助重新编写一些最初使用名为 Squeel 的 gem 编写的 Rails DB 查询,具有有效的 SQL的主要内容,如果未能解决你的问题,请参考以下文章

QFile 和 QTextStream 帮助(使用用户名、密码和名称为用户编写 ID)

Ruby Gem Squeel,如何编写自联接

Squeel 子查询

Rails,ActiveRecord,Squeel:检查数组中是不是存在值

ruby on rails 连接条件(带 squeel)

使用 active admin、polyamorous、activerecord 更新 squeel