Fel*_*van 5 postgresql activerecord ruby-on-rails
假设我的Parent模型有很多Child,Child也属于OtherParent.
我怎样才能找到所有属于Parent它的所有地方?ChildOtherParent
在纯SQL中我能做到
Parent.find_by_sql(<<SQL)
SELECT *
FROM parents p
WHERE NOT EXISTS (
SELECT *
FROM children
WHERE parent_id = p.id
AND other_parent_id IS NULL
)
SQL
Run Code Online (Sandbox Code Playgroud)
(从这里开始),但如果可能的话,我更愿意利用ActiveRecord.
谢谢!
我正在使用Rails 4.2.1和PostgreSQL 9.3
使用arel可以让你走得更远。棘手的部分是如何不使用arel自己的查询语法编写整个查询?
这里有一个技巧:在使用 构建查询时where,如果使用arel条件,则可以免费获得一些额外的方法。例如,您可以使用 尾部子查询.exists.not,这将使您将(NOT ( EXISTS (subquery)))其扔到父级的where- 子句中,然后就可以了。
问题是,如何引用涉及的表?为此你需要阿雷尔。您可以使用 Arel 的where丑陋条件,例如a.eq b. 但为什么?由于它是一个相等条件,因此您可以使用 Rails 的条件来代替!您可以使用哈希键引用要查询的表,但对于其他表(在外部查询中),您可以使用其arel_table. 看这个:
parents = Parent.arel_table
Parent.where(
Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)
Run Code Online (Sandbox Code Playgroud)
您甚至可以通过稍微求助于字符串并依赖于可以将子查询作为 Rails 的参数提供的事实来减少 Arel 的使用where。它没有太多用处,但它不会强迫您过多地研究 Arel 的方法,因此您可以使用该技巧或其他采用子查询的 SQL 运算符(还有其他吗?):
parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
Child.where(parent_id: parents[:id], other_parent_id: nil)
)
Run Code Online (Sandbox Code Playgroud)
这里的两个要点是:
where方法的参数。| 归档时间: |
|
| 查看次数: |
1009 次 |
| 最近记录: |