不明确的列“id”在 ActiveRecord 查询中

发布于 2024-11-07 12:43:49 字数 1958 浏览 1 评论 0原文

我有一些复杂的 ActiveRecord (2.3.8) 模型(不是真的,一些关联和命名范围,以及一个缓存值),并且在我的应用程序中的某处,我看到出现以下 MySQL (5.1) 查询:

SELECT `cases`.id FROM `cases`
INNER JOIN `contracts` ON `cases`.contract_id = `contracts`.id
WHERE ((case_status_id = 0 AND case_status_id IS NOT NULL) AND id = XXXX)
AND ((`cases`.`archived` = 0)
AND ((`contracts`.customer_id = XXXX)))
LIMIT 1

显然不是最可读的查询。有时,ActiveRecord 会抱怨“id”列不明确,我必须同意:-)

然而,只有当数据库中的数据“稀疏”时,才会发生这种情况。我们有一个导入脚本来填充这些表,插入的数据越多,这些错误就越少。

触发异常的代码:

paginate_options = {:page => params[:page], :per_page => 25 }
options = paginate_options.merge(:include => [:active_status, :case_summary], :order => @sortable.order)
@cases = current_customer.cases.unarchived.paginate(options)

“活动状态”字段的缓存位置:

belongs_to    :active_status, 
            :class_name   => "CaseStatus", 
            :foreign_key  => 'case_status_id'
caches_value  :case_status_id, 
            :sql => 'SELECT id FROM case_statuses WHERE case_id = #{id} ORDER BY id DESC LIMIT 1'

堆栈跟踪如下所示:

config/initializers/connection_fix.rb:  17:in `execute'
vendor/plugins/cached_values/lib/cached_value.rb:  91:in `update_cache'
vendor/plugins/cached_values/lib/cached_value.rb:  14:in `load'
vendor/plugins/cached_values/lib/cached_values.rb:  85:in `case_status_id'
plugins/will_paginate/lib/will_paginate/finder.rb:  82:in `paginate'
plugins/will_paginate/lib/will_paginate/collection.rb:  85:in `create'
plugins/will_paginate/lib/will_paginate/finder.rb:  76:in `paginate'

所以我假设第一次尝试刷新缓存时会发生此错误。该查询似乎由 cached_values 插件使用并位于 will_paginate 语句内,但该语句中使用的缓存查询不会出现在上面的查询中。

我也不明白为什么 ActiveRecord 会在还有 id=XXXX 语句时查询 cases.id 。我假设两者都查询相同的id,但话又说回来,它相当不明确。

我有什么办法可以告诉 ActiveRecord 使用显式表名称吗?或者调试此查询的构造方式的方法? “cached_values”插件是否可能受到命名范围的影响,有没有办法解决这个问题?

I have somewhat complex ActiveRecord (2.3.8) models (not really, some associations and named scopes, and one cached value) and somewhere in my application I see the following MySQL (5.1) query appear:

SELECT `cases`.id FROM `cases`
INNER JOIN `contracts` ON `cases`.contract_id = `contracts`.id
WHERE ((case_status_id = 0 AND case_status_id IS NOT NULL) AND id = XXXX)
AND ((`cases`.`archived` = 0)
AND ((`contracts`.customer_id = XXXX)))
LIMIT 1

Obviously not the most readable query. Sometimes ActiveRecord complains that the column 'id' is ambiguous, and I have to agree :-)

This only happens however, when the data in the database is 'sparse'. We have an import script that fills up these tables, and the more data is inserted, the less frequent these errors become.

The code triggering the exception:

paginate_options = {:page => params[:page], :per_page => 25 }
options = paginate_options.merge(:include => [:active_status, :case_summary], :order => @sortable.order)
@cases = current_customer.cases.unarchived.paginate(options)

Where the 'active status' field is cached:

belongs_to    :active_status, 
            :class_name   => "CaseStatus", 
            :foreign_key  => 'case_status_id'
caches_value  :case_status_id, 
            :sql => 'SELECT id FROM case_statuses WHERE case_id = #{id} ORDER BY id DESC LIMIT 1'

The stacktrace looks like this:

config/initializers/connection_fix.rb:  17:in `execute'
vendor/plugins/cached_values/lib/cached_value.rb:  91:in `update_cache'
vendor/plugins/cached_values/lib/cached_value.rb:  14:in `load'
vendor/plugins/cached_values/lib/cached_values.rb:  85:in `case_status_id'
plugins/will_paginate/lib/will_paginate/finder.rb:  82:in `paginate'
plugins/will_paginate/lib/will_paginate/collection.rb:  85:in `create'
plugins/will_paginate/lib/will_paginate/finder.rb:  76:in `paginate'

So I assume this error happens trying to refresh the cache for the first time. The query appears to be used by the cached_values plugin and inside a will_paginate statement, but the cached query used in that statement does not appear in the query above.

I also do not understand why ActiveRecord would query cases.id when there is also an id=XXXX statement. I assume both query the same id, but then again, it is quite ambiguous..

Any way I can tell ActiveRecord to use explicit table names? Or a way to debug the way this query is constructed? Is the 'cached_values' plugin maybe affected by named scopes and is there a way around that?

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文