我有问题。之前我发布了一个类似的问题,我要问的是哪个问题得到了解答,可以在这里找到上下文ActiveRecord Count and SQL count do not match
这个问题与计算查询结果有关。在这个问题中,我得到的是不同的对象结果,而不是得到相同的计数结果。
这是ActiveRecord代码:
scope :unverified_with_no_associations, -> {
find_by_sql("SELECT DISTINCT(accounts.id, accounts.email) FROM accounts WHERE level = 0 AND id NOT IN
(SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN
(SELECT DISTINCT(account_id) FROM positions) AND id NOT IN
(SELECT DISTINCT(account_id) FROM edits) AND id NOT IN
(SELECT DISTINCT(account_id) FROM posts) AND id NOT IN
(SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN
(SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN
(SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL)")
这会返回[#<Account:0x007f96bf143c70 id: >]
并在sql输出unknown OID 2249: failed to recognize type of 'row'. It will be treated as String.
如果我在数据库中运行上面的sql代码,我将检索我需要的内容:
-------row-------
(1234,me@gmail.com)
导致这种不匹配的原因是什么,我该如何避免它。我发现这篇关于自定义postgres类型Custom postgres types的帖子,但这看起来我需要了解事物的细节,我想避免这种情况。有人知道为什么这是一个问题吗?
答案 0 :(得分:1)
您遇到此问题是因为ActiveRecord无法将此行识别为您帐户表格中的行。 AR没有解析你的sql而且它不知道如何处理匿名皮质。
如果您使用find_by_sql
所选属性未正确映射到您的模型但仍可访问,请尝试:
result.id
result.email
但你也有两种方法可以解决这个问题。
首先(这是非常讨厌但很简单的解决方案),将您的sql转换为Arel
,即范围的虚拟内容:
scope :unverified_with_no_associations, -> {
send(:default_scoped).from(Arel.sql("(SELECT * FROM accounts WHERE level = 0 AND id NOT IN
(SELECT DISTINCT(account_id) FROM verifications) AND id NOT IN
(SELECT DISTINCT(account_id) FROM positions) AND id NOT IN
(SELECT DISTINCT(account_id) FROM edits) AND id NOT IN
(SELECT DISTINCT(account_id) FROM posts) AND id NOT IN
(SELECT DISTINCT(account_id) FROM reviews) AND id NOT IN
(SELECT DISTINCT(sender_id) FROM kudos) AND id NOT IN
(SELECT DISTINCT(account_id) FROM stacks WHERE account_id IS NOT NULL))
AS accounts"))
...并调用AR不同的方法:
Account.unverified_with_no_associations.select(:id, :email).distinct
第二(这是更好的解决方案):
不要直接使用sql。使用Arel
(https://github.com/rails/arel)或squeel
(https://github.com/activerecord-hackery/squeel)