我很困惑何时/如何使用rails'Joint方法与rails'Associations。
我有一组对象以类似火车的方式相互链接:类A
has_many: bs
和类B
has_many: cs
。我想在与c
链接的所有B
链接的所有A
上调用方法。我尝试使用a.bs.cs.some_method
执行此操作并获得
undefined method 'some_method' for #<bs::ActiveRecord_Associations_CollectionProxy:…>
在搜索之后,我逐渐明白这意味着a.bs
返回一个CollectionProxy对象,你无法调用方法 - 即使是类c
具有的方法 - on c
个对象的CollectionProxy对象。
我试图找出它应该如何完成,然后遇到Joins
。现在我想知道是否应该使用嵌套连接来做这种事情呢?我以为我已经看到了一长串关联用来做这件事,但我可能错了。
所以,我的问题是:
1 - 这样做的正确方法是什么?
2 - 如果可以使用joins
和关联链接完成,何时应该使用另一个?
答案 0 :(得分:1)
首先,如果您想获取被收集的被告对象或方法输出,请使用fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
或collect
。
即
map
现在上面的行将以数组格式给出结果,但它非常昂贵。为什么,因为它将运行像这样的查询
1)第一次查询以获取 a.bs.collect{|b| b.cs.collect(&:method_name)}.flatten.compact
(此罚款)
2)使用IN查询获取a
的所有bs
的第二个查询(这也很好,因为IN查询只是1个查询,并且不会花费那么多时间)
3)第3名:现在,对于每个a
,它会尝试获取b
,而获取cs
的查询数量将取决于cs
的数量。这非常昂贵。
我们将在获取bs后急切加载 b
cs
。这种方式而不是明确地每次运行bs
的查询,它将使用cs
运行一个查询,这很好
IN
详情:
这将运行1个查询以获取 a.bs.includes(:cs).collect{|b| b.cs.collect(&:method_name)}.flatten.compact
,1个查询以获取关联的a
bs
然后使用一个查询来获取a
的相关cs
。
您可以从此链接中了解热切加载概念,并且在获取大规模数据时这是非常有用的概念。 http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
要获取详细信息,请尝试此操作
#fetch some this for this bs
a = A.first