我有两个模型:AssetItem 和 Title。
- 一个 AssetItem 属于一个 Title / Title 有很多 assets_items。
- 一个 Title 可以有一个父 Title(从而创建一个层次结构);Titles 中的这种父/子关系由祖先 gem 管理。
我有一个控制器正在获取一堆 AssetItems。这些 AssetItems 应该带有它们的 Title、Title 的父级和Title的父级等等。最后,控制器以 JSON 格式呈现此对象图。我正在尝试找到一种方法来为给定的资产项急切加载所有标题层次结构。
我在我的控制器中这样做:
def show
asset_items = AssetItem.includes(:title).where(:id => list_of_ids)
eager_load_titles_for(asset_items)
respond_with asset_items, serializer: AssetItemSerializer
end
private
def eager_load_titles_for(asset_items)
title_ids = asset_items.map { |a| a.title.ancestor_ids }.flatten
Title.find(title_ids) # these titles are not really used, this is just to eager load them
end
这个想法是,获取资产项的集合,然后简单地加载(但不使用)与这些资产项关联的标题 ID,这样当序列化程序执行类似 object.parent.parent.parent.some_attribute 的操作时,它从缓存中获取该标题,而不是从数据库中获取。
但是,日志中的结果与我的预期不符:
10:19:27 web.1 | AssetItem Load (1.3ms) SELECT "asset_items".* FROM "asset_items" WHERE "asset_items"."id" IN (291, 311, 316, 309, 323, 304, 296, 289, 328, 284, 373, 342, 330, 335, 361, 366, 354, 347, 359, 380, 400, 405, 392, 378, 397, 417, 412, 385, 436, 429, 450, 448, 431, 455, 462, 424, 443, 481, 498, 467, 501, 493, 474, 506, 486, 479, 532, 525, 520, 513)
10:19:27 web.1 | Title Load (0.6ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" IN (167, 182, 188, 203, 227, 242, 248, 263, 284, 299, 305, 320, 341, 356, 377, 392, 398, 413, 434, 449, 455, 470, 491, 506, 515, 530, 551, 566, 587, 602, 608, 623, 644, 659, 665, 680, 701, 716, 737, 752, 758, 773, 794, 809, 818, 833, 854, 875, 890, 911)
10:19:27 web.1 | Title Load (0.9ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" IN (186, 187, 246, 247, 261, 262, 240, 241, 282, 283, 225, 226, 201, 202, 180, 181, 297, 298, 165, 166, 432, 433, 339, 340, 303, 304, 318, 319, 396, 397, 411, 412, 375, 376, 354, 355, 390, 391, 453, 454, 513, 514, 528, 529, 489, 490, 447, 448, 504, 505, 564, 565, 549, 550, 468, 469, 621, 622, 600, 601, 663, 664, 657, 658, 606, 607, 678, 679, 699, 700, 585, 586, 642, 643, 756, 757, 807, 808, 714, 715, 816, 817, 792, 793, 735, 736, 831, 832, 771, 772, 750, 751, 909, 910, 888, 889, 873, 874, 852, 853)
10:19:27 web.1 | CACHE (0.0ms) SELECT "asset_items".* FROM "asset_items" WHERE "asset_items"."id" IN (291, 311, 316, 309, 323, 304, 296, 289, 328, 284, 373, 342, 330, 335, 361, 366, 354, 347, 359, 380, 400, 405, 392, 378, 397, 417, 412, 385, 436, 429, 450, 448, 431, 455, 462, 424, 443, 481, 498, 467, 501, 493, 474, 506, 486, 479, 532, 525, 520, 513)
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" IN (167, 182, 188, 203, 227, 242, 248, 263, 284, 299, 305, 320, 341, 356, 377, 392, 398, 413, 434, 449, 455, 470, 491, 506, 515, 530, 551, 566, 587, 602, 608, 623, 644, 659, 665, 680, 701, 716, 737, 752, 758, 773, 794, 809, 818, 833, 854, 875, 890, 911)
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" IN (186, 187, 246, 247, 261, 262, 240, 241, 282, 283, 225, 226, 201, 202, 180, 181, 297, 298, 165, 166, 432, 433, 339, 340, 303, 304, 318, 319, 396, 397, 411, 412, 375, 376, 354, 355, 390, 391, 453, 454, 513, 514, 528, 529, 489, 490, 447, 448, 504, 505, 564, 565, 549, 550, 468, 469, 621, 622, 600, 601, 663, 664, 657, 658, 606, 607, 678, 679, 699, 700, 585, 586, 642, 643, 756, 757, 807, 808, 714, 715, 816, 817, 792, 793, 735, 736, 831, 832, 771, 772, 750, 751, 909, 910, 888, 889, 873, 874, 852, 853)
10:19:27 web.1 | Title Load (0.4ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 186]]
10:19:27 web.1 | Title Load (0.2ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
10:19:27 web.1 | CACHE (0.0ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
如您所见,最初标题 ID 186 和 187 被加载到这里的 where 子句中:
10:19:27 web.1 | Title Load (0.9ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" IN (186, 187, 246, 247, 261, 262, 240, 241, 282, 283, 225, 226, 201, 202, 180, 181, 297, 298, 165, 166, 432, 433, 339, 340, 303, 304, 318, 319, 396, 397, 411, 412, 375, 376, 354, 355, 390, 391, 453, 454, 513, 514, 528, 529, 489, 490, 447, 448, 504, 505, 564, 565, 549, 550, 468, 469, 621, 622, 600, 601, 663, 664, 657, 658, 606, 607, 678, 679, 699, 700, 585, 586, 642, 643, 756, 757, 807, 808, 714, 715, 816, 817, 792, 793, 735, 736, 831, 832, 771, 772, 750, 751, 909, 910, 888, 889, 873, 874, 852, 853)
然后在此之下,我们再次看到:
10:19:27 web.1 | Title Load (0.4ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 186]]
10:19:27 web.1 | Title Load (0.2ms) SELECT "titles".* FROM "titles" WHERE "titles"."id" = $1 LIMIT 1 [["id", 187]]
这就是为什么我想知道我做错了什么。任何帮助将不胜感激。