我有四张桌子:
带有字段的参数
评论
用户
昵称
每个论点都有很多评论,
每个评论属于用户,
每个用户在参数中都有一个特定的昵称。
当我从DB获取参数评论时,我想也包括每个作者的昵称。
答案是关于 ActiveRecord查询我不知道怎么写。
我试过
@argument.comments.includes(:user => :nicknames)
但它似乎不起作用,当我得到昵称 nickname = @ argument.nicknames.find_by_user_id(comment.user.id) 它执行查询...
[1m[36mNickname Load (0.6ms)[0m [1mSELECT "nicknames".* FROM "nicknames" WHERE "nicknames"."argument_id" = 59 AND "nicknames"."user_id" = 9 LIMIT 1[0m
任何建议?
答案 0 :(得分:2)
您可以判断某个关联是否加载了loaded?
。
这里发生的事情,如果我理解你的问题,那就是你试图在ActiveRecord :: Relation上运行一个finder。快速浏览the code,它似乎不会在发出查询之前尝试查看集合是否已加载。但是,它确实采用了一个避免多次查询的块。例如(模型名称已更改,因为我正在使用我为另一个问题创建的示例项目):
c = Canteen.first
Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1
=> #<Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11">
c.meals.loaded?
=> false
c.meals.find {|m| m.id == 3}
Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1
=> #<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb6784fa78,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41">
您在上一个示例中看到ActiveRecord发出查询以加载关联的记录。这是因为ActiveRecord在关联上调用to_a
,强制加载整个集合,然后根据块条件进行过滤。显然,这并不理想。
让我们再试一次,急切加载协会。
c = Canteen.includes(:meals).first
Canteen Load (0.2ms) SELECT "canteens".* FROM "canteens" LIMIT 1
Meal Load (0.2ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" IN (1)
=> #<Canteen id: 1, name: "Really good place", created_at: "2012-12-13 00:04:11", updated_at: "2012-12-13 00:04:11">
c.meals.loaded?
=> true
c.meals.find {|m| m.id == 3}
=> #<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb68b596f0,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41">
在此处的最后一个示例中,您会看到未再次加载该集合。相反,该块用于过滤已加载的记录。
如下所示,即使加载了记录,ActiveRecord也会发出查询以获取相关记录:
c.meals.loaded?
=> true
c.meals.find(1)
Meal Load (0.1ms) SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = ? LIMIT 1 [["id", 1]]
=> #<Meal id: 1, canteen_id: 1, name: "Enchiladas", price: #<BigDecimal:7fcb6584ce88,'0.699E1',18(45)>, created_at: "2012-12-13 00:04:40", updated_at: "2012-12-13 00:04:40">
SELECT "meals".* FROM "meals" WHERE "meals"."canteen_id" = 1 AND "meals"."id" = 3
=> [#<Meal id: 3, canteen_id: 1, name: "Banana Pie", price: #<BigDecimal:7fcb68b808e0,'0.499E1',18(45)>, created_at: "2012-12-13 00:37:41", updated_at: "2012-12-13 00:37:41">]
答案 1 :(得分:0)
可能是这样的:
@argument.includes(:comments => [{ :user => :nicknames }])
虽然没试过......
答案 2 :(得分:0)
你可以尝试这样的东西来包含多个表
User.find(:all, :include => Room.find(:all,:include => :review))