HABTM发现带有``ND'';一个联系,而不是``R''个联接。
技术问答
243 人阅读
|
0 人回复
|
2023-09-14
|
我有两个与HABTM相关模型(实际上在两端使用)has_many:through还有连接表)。我需要检索两个ModelB所有相关的ModelAs。我不希望将ModelB_1的所有ModelA与ModelB_2的所有ModelA串联在一起。我真的希望一切都和我在一起。ModelB_1和ModelB_2都关联的ModelAs。它不限于两个ModelB,最多可包个ModelB,因此必须扩展。
9 C- K- Q( Q- ~' k' s1 i我可以用各种类比来描述问题,我认为它比上一段更好地描述了我的问题:+ C' H, a7 ~) n% } g; F( V4 \+ k7 I
* Find all books that were written by all 3 authors together.* Find all movies that had the following 4 actors in them.* Find all blog posts that belonged to BOTH the Rails and Ruby categories for each post.* Find all users that had all 5 of the following tags: funny,thirsty,smart,thoughtful,and quick. (silly example!)* Find all people that have worked in both San Francisco AND San Jose AND New York AND Paris in their lifetimes.我想到了很多方法来实现这一目标,但它们的效率很低,而且感觉很皱眉。
* }9 D% N1 A N3 h+ w以上类比为例。最后,您可以查询每个城市的所有人,然后在每个数组中找到每个数组中存在的项目。至少有5个查询,所有这些查询的数据都被传输回应用程序,然后应用程序必须密集比较所有5个数组(大量循环)!)。太烦了吧?
, Z1 N) q- G* p) v3 ~5 r/ M" g+ a另一个可能的解决方案是将搜索结果链接在一起,与上述操作基本相同,但不会消除多个查询和处理。此外,如果您有用户提交的可能高达50个选项,您将如何动态链?看起来很脏。你需要一个循环。第三,这将增加搜索的持续时间。
. F% p2 r/ e2 c6 u. P+ t显然,如果可能的话,我们希望数据库能为我们执行这个操作,所以有人建议我只需要输入多个条件。不幸的是,它通常是正确的HABTM或操作。6 ^7 e/ X7 x: [' ^+ X$ z& e
我遇到的另一个解决方案是使用搜索引擎,例如sphinx或UltraSphinx。对于我的特殊情况,我认为这太过分了。我宁愿避免这种情况。我仍然认为应该有一个解决方案,让用户可以处理任何数量ModelB查询并找到一切ModelA。* p% E$ c' O8 m8 Q, j9 @- k
你将如何解决这个问题?
2 X" ?# e b5 M! V8 f' | " W- i. h: T, @. B. ]- o. \. Q& l
解决方案: ) z! B$ h. ^& [, W3 ~# a% y
可以这样做:" B7 o. L% J, \5 ^; Y# u
[ol]从您的ModelA构建查询,然后添加(通过连接模型)ModelB,过滤器具有您想要找到的值之一ModelB,把它们放进去OR(即where ModelB = 'ModelB_1' or ModelB = 'ModelB_2')。通过此查询,结果集将具有多个“ ModelA行,对于每一个满足ModelB条件,银行只是一行 。
9 H( K: N+ d6 c8 `8 S s" N在您需要的ModelA根据条件在列查询中添加一组(如有必要,甚至可以全部添加)。的count( )等于满足ModelB条件数*。7 ]/ T# o7 C) q$ j
只选择添加有条件count(*)等于你需要满足ModelB条件数的行+ H2 }* j& \! K- I+ @5 u) I
[/ol]例子:
7 V7 ]4 i; k6 U; P$ m$ D" r. c. `model_bs_to_find = [100,200]ModelA.all( :joins=>{:model_a_to_b=>:model_bs}, group=>"model_as.id", select=>"model_as.*", conditions=>["model_bs.id in (?)",model_bs_to_find], having=>"count(*)=#{model_bs_to_find.size}")请注意,以这种方式指定的组和选择参数将在MySQL工作,这样做的标准SQL方法是整体model_as列表放入组和选择参数中。 |
|
|
|
|
|