Rails ActiveRecord:动态构建查询

发布于 2024-11-08 18:00:13 字数 540 浏览 0 评论 0原文

我试图将一系列可以使用 ActiveRecord 动态创建和执行复杂查询的类组合在一起。我对整个实践感到非常满意:

MyModel.select("id, name, floober").join(:creator).where(:is_active => true)

我正在努力使用这些东西来构建一个查询,而无法确定每种可能的方法有多少(连接数、数量或位置)条款、限制、组等)提前。我可能有 2 个连接,也可能没有连接,具体取决于调用的位置。

由于我获取这些东西的方式的本质——连接列表、列列表、where 子句列表等——我可以盲目地将它们链接在一起。我必须将列连接在一起,排列连接,链接 where 子句,所以我无法循环遍历各个列表。

我试图避免编写任何原始 SQL。

我尝试过的一件事是将 ruby​​ 语句构建为字符串,然后在最后对其进行评估,当我完成时,我感觉很脏,就像我需要洗澡一样。我正在寻找一种方法来缓存查询的状态,直到所有部分都已累积,然后执行它们。

我是否已经“偏离轨道”了?

提前致谢...

I'm trying to put together a series of classes that can use ActiveRecord to create and execute complex queries dynamically. I feel very comfortable with the whole practice of doing:

MyModel.select("id, name, floober").join(:creator).where(:is_active => true)

What I'm struggling with is using these things to build up a query w/o being able to determine how many there will be of each possible method (number of joins, number or where clauses, limit, group, etc) ahead of time. I might have 2 joins, or no joins depending upon where it's called from.

Due to the nature of how I'm getting these things--a list of joins, a list of columns, a list of where clauses, etc--I can blindly chain them together. I have to join the columns together, arrange the joins, chain the where clauses, so I can't loop through the various lists.

I'm trying to avoid writing any raw SQL.

One thing I tried was building up the ruby statement as a string then evaling it at the end, and when I got done I felt dirty like I needed a bath. What I'm looking for is a way to cache the state of my query until all the parts have been accumulated, then execute them.

Have I wandered "off the Rails"?

thanks in advance...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

歌枕肩 2024-11-15 18:00:13

我想我明白了。我对 AR 查询方法的理解相当偏差。事实证明,在您实际尝试使用结果之前,ActiveRecord 并不真正执行查询。因此,可以执行以下操作:

model_query = MyModel.select("column12, column32")
model_query = model_query.joins(:user)
model_query = model_query.where(:column12 => true)

然后在所有内容都建立之后,您可以执行

model_query.each do |record|
  ...
end

该查询,直到您调用每个(或您使用的任何需要查询结果的方法)才真正执行查询。

我通过观看 Railscasts 202215。我爱瑞安·贝茨。

I think I figured it out. I was fairly off base on my understanding of the AR query methods. It turns out that ActiveRecord doesn't actually execute the query until you actually try to use the results. As a result it's possible to do things like:

model_query = MyModel.select("column12, column32")
model_query = model_query.joins(:user)
model_query = model_query.where(:column12 => true)

then after everything is built up you can do

model_query.each do |record|
  ...
end

The query isn't actually executed until you call each (or whatever method you use that demands the results of the query).

I got this by watching Railscasts 202 and 215. I love Ryan Bates.

゛时过境迁 2024-11-15 18:00:13

在这种情况下,send 可能是您的朋友。它仍然是相当任意的代码执行,但至少你没有使用eval。目前尚不完全清楚您是一次性拥有这些查询部分还是随着时间的推移逐渐构建它们。如果它们出现在一个 http 请求/响应周期中,则根据需要迭代查询部分并执行 send 是有意义的。

OTOH,如果您通过 Ajax 或其他条件累积的方式获取它,您可能需要考虑缓存现有部分或一些更奇特的解决方案。

In this case, send may be your friend. It's still pretty arbitrary execution of code, but at least you're not using eval. It's not entirely clear whether you have these query parts all at once or are building them up over time. If they are present in one http request/response cycle, then iterating through the query parts and doing a send, as appropriate would make sense.

OTOH, if you are getting it via Ajax or some other means where the conditions are cumulative, you may have to look at either caching the existing parts or some more exotic solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文