我试图通过检查它的几个关系来找到一个对象。
Loan.joins(:credit_memo_attributes)
.where(credit_memo_attributes: {name: 'pr2_gtx1_y', value: '2014'})
.where(credit_memo_attributes: {name: 'pr1_gtx1_y', value: '2013'})
.where(credit_memo_attributes: {name: 'tx1_y', value: '2014'})
调用to_sql
就可以了:
"SELECT `loans`.* FROM `loans` INNER JOIN `credit_memo_attributes`
ON `credit_memo_attributes`.`loan_id` = `loans`.`id`
WHERE `credit_memo_attributes`.`name` = 'pr2_gtx1_y' AND `credit_memo_attributes`.`value` = '2014'
AND `credit_memo_attributes`.`name` = 'pr1_gtx1_y' AND `credit_memo_attributes`.`value` = '2013'
AND `credit_memo_attributes`.`name` = 'tx1_y' AND `credit_memo_attributes`.`value` = '2014'"
所以,我正在检查具有所有这些属性的credit_memo_attributes的贷款。我知道我们的20,000笔贷款中至少有一笔符合此条件,但此查询返回一个空集。如果我只使用where
子句中的一个,它会返回几个,正如我所期望的那样,但是一旦我再添加一个,它就是空的。
知道我哪里出错了?
答案 0 :(得分:1)
根据评论我相信您希望在您的条件中加入多个联接。你可以这样做:
attr_1 = {name: 'pr2_gtx1_y', value: '2014'}
attr_2 = {name: 'pr1_gtx1_y', value: '2013'}
attr_3 = {name: 'tx1_y', value: '2014'}
Loan.something_cool(attr_1, attr_2, attr_3)
class Loan < ActiveRecord::Base
...
def self.something_cool(attr_1, attr_2, attr_3)
joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma1 ON cma1.loan_id = loans.id AND cma1.name = :name AND cma1.value = :value", attr_1]))
.joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma2 ON cma2.loan_id = loans.id AND cma2.name = :name AND cma2.value = :value", attr_2]))
.joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma3 ON cma3.loan_id = loans.id AND cma3.name = :name AND cma3.value = :value", attr_3]))
end
如果您查看生成的SQL(包含在您的问题中,谢谢),您将看到所有这些条件正在进行AND运算。没有名称=&#39; pr2_gtx1_y&#39; AND name =&#39; pr1_gtx1_y&#39; (等等)。所以你得到了我期望的结果(没有行)。
答案 1 :(得分:0)
您可以将所有名称和值放入数组中,如id和years,并将其传递到where子句中。 Active Record将查询数组中的所有值。
Loan.joins(:credit_memo_attributes)
.where(credit_memo_attributes: {name: ids, value: years})
就我个人而言,我仍然在学习积极的记录,在这种担忧中我并不认为积极的记录支持多个where子句。
答案 2 :(得分:0)
请注意SQL
版本如何返回您的代码:它使用AND
加入要求。
"SELECT `loans`.* FROM `loans` INNER JOIN `credit_memo_attributes`
ON `credit_memo_attributes`.`loan_id` = `loans`.`id`
WHERE `credit_memo_attributes`.`name` = 'pr2_gtx1_y' AND `credit_memo_attributes`.`value` = '2014'
AND `credit_memo_attributes`.`name` = 'pr1_gtx1_y' AND `credit_memo_attributes`.`value` = '2013'
AND `credit_memo_attributes`.`name` = 'tx1_y' AND `credit_memo_attributes`.`value` = '2014'"
现在,这几乎是不可能的。 Object.name
永远不可能是pr2_gtx1_y
,pr1_gtx1_y
和tx1_y
。 value
属性也是如此。
这里需要的是OR
,而不是AND
。
为此,请尝试将查询更改为以下内容:
Loan.joins(:credit_memo_attributes)
.where(
"credit_memo_attributes.name = ? and credit_memo_attributes.value = ?
OR credit_memo_attributes.names = ? and credit_memo_attributes.value = ?
OR credit_memo_attributes.name = ? and credit_memo_attributes.value = ?",
'pr2_gtx1_y', '2014',
'pr1_gtx1_y', '2013',
'tx1_y', '2014'
)