使用 Arel 进行嵌套集合 &连接查询并转换为 ActiveRecord::Relation
我有一个组织模型(嵌套集)。我有一个人们的榜样。一个人可以有另一个人作为副手。组织归个人所有。组织仅对其所有者或其代理人可见。
我想检索给定人员可见的所有组织,即。该人拥有的或由人拥有的所有组织,该人是代表:
o = Arel::Table.new(:organisations)
p = Arel::Table.new(:people)
pd = p.where(p[:id].eq(3).or(p[:deputy_id].eq(3))).project(:id)
op = o.join(p).where(o[:person_id].in(pd)).project("distinct organisations.*)
可能有更好的方法来制定最后一个连接,但我想将人员及其代表的查询与组织的查询分开人们及其代表可见。
最后一个连接返回一个 Arel::SelectManager (似乎没有任何有用的文档)。
有没有办法将 SelectManager 转换回 ActiveRecord::Relation 以便从“组合下的闭包”的整个概念中受益?
如何再次自行加入上述组织查询,以获取个人或其代理人可见的组织的所有后代?我知道 SQL,但使用 SelectManager 对组织进行自连接总是失败。
I have a model for organisations (nested set). I have a model for people. A person can have another person as deputy. An organisation is owned by a person. An organisation is only visible to the owning person or their deputy.
I would like to retrieve all organisations visible by a given person, ie. all organisations owned by that person or owned by people, for which the given person is a deputy:
o = Arel::Table.new(:organisations)
p = Arel::Table.new(:people)
pd = p.where(p[:id].eq(3).or(p[:deputy_id].eq(3))).project(:id)
op = o.join(p).where(o[:person_id].in(pd)).project("distinct organisations.*)
There is probably a better way to formulate the last join, but I would like to split the query for people and their deputies from the query of organisations visible to people and their deputies.
The last join returns a Arel::SelectManager (for which there seems no useful documentation anywhere).
Is there a way to convert the SelectManager back into an ActiveRecord::Relation to benefit from the whole concept of "closure under composition"?
How do I self join the above query on organisations again to obtain all descendants of the organisations visible to a person or their deputy? I know the SQL but always fail with the SelectManager to do the self join on organisations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
似乎没有人接受任何答案,我自己找到了解决方案:
1。将最后一个连接转换为
ActiveRecord::Relation
唯一的问题是,这会调用
Arel::SelectManager.to_a
,并附带弃用警告(并且也是一项昂贵的操作)。不过,我还没有找到替代方案(怀疑没有替代方案,并且此弃用警告只是 Arel 中可观察到的不一致之处之一,并且在 ActiveRecord 中采用了它)。2.在嵌套集上自连接以获取所有后代
Seems there are no takers for any answer and I've found a solution approach myself:
1. Convert the last join to an
ActiveRecord::Relation
The only issue with this is that this calls
Arel::SelectManager.to_a
which comes with a deprecation warning (and is also an expensive operation). I haven't found an alternative though (suspect there is none and this deprecation warning is just one of the inconsistencies observable in Arel and it's adoption in ActiveRecord).2. Self-join on nested set to get all descendants
你也可以这样做:
我也在搜索了一段时间后得到了这个。这将允许您在其上堆叠任何其他范围。
You could also do:
I got this after searching a while too. This will allow you to stack any other scope over it.
您应该能够在
Arel::SelectManager
实例上调用join_sources
,该实例可以传递给ActiveRecord::Relation#joins
。您的查询将如下所示(未经测试):You should be able to call
join_sources
on an instance ofArel::SelectManager
, which can be passed toActiveRecord::Relation#joins
. Your query would look like this (untested):