这是我的基本模型层次结构:
Movie has many Listings and many Links through Listings
Listing has many Links
Link has a price (float)
我正在尝试获取所有包含价格= 0.00的链接的电影。
我可以使用范围轻松完成此操作:
scope :free, lambda{
joins(:links).where('links.price = ?', 0.00)
.group('movies.id')
}
这给我提供了一个有免费链接的电影列表,这一切都很好,但当我经历并实际查看Movie.links
时,它给了我所有链接,而不仅仅是免费链接。这是问题一。
问题二是当我在db中获取它们的列表时,我需要有效地预取几个Movie的关系。为此,我使用includes()
,如下所示:
default_scope includes(
:formats,
:critic_ratings => [
:network
],
:covers => [
:network
],
:listings => [
:links, :network
]
)
这也有效,但它与之前的免费范围不兼容。这就是说它将获取电影的所有属性,而不仅仅是免费的属性,而且我不知道如何在复杂的包含语句中规定对项目的任何限制。我希望能够仅预取链接where('price = ?', 0.00)
。我现在使用它的方式,我使用此default_scope
获取所有列表和链接,然后运行一个单独的.free
范围,我已经为我的部分渲染页面中的列表建立了范围。但是当我这样做时,查询会回到db,我认为这比我只是用我自己的简单检查手动过滤内存中的预取结果要快得多。
总结:
问题一:正确地分组或设置我的范围,以便Movie.links只提供免费链接而不强迫我回到db(即我知道我可以做Movie.links.free w / free是一个为Link定义的范围,但据我所知,这将返回到db。如果没有使用范围和分组的问题一的内置解决方案,我可以实现一个帮助程序来进行内存中的后期排序来解决这个问题,尽管它会给复杂的情况带来一些麻烦。
问题二:我希望我的范围根据我规定的条件预先获取一组精选的列表,链接等。如果我们无法解决问题一,可能没有问题二的解决方案,因为我无法知道哪些链接已被预取,我将不得不重新扫描它们以找到免费的链接,除非电影.links只给我免费的(Movie.where()会回到db吗?)。
希望这不会太混乱。谢谢你的帮助。