需要帮助重新编写一些最初使用名为 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 有效,据我所知,它已经过去了。
Fleet
和 Vendor
是 has_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)