5

我有四张桌子:

带字段的参数

  • ID

评论

  • ID
  • comment_id
  • argument_id
  • 用户身份

用户

  • ID

昵称_

  • ID
  • 提案编号
  • 用户身份
  • 姓名

每个论点都有很多评论,

每条评论都属于一个用户,

每个用户在参数中都有一个特定的昵称。

当我从 DB 获取论点评论时,我还想包括每个作者的昵称。

答案是关于我不知道如何编写的 ActiveRecord 查询

我试过了

@argument.comments.includes(:user => :nicknames)

但它似乎不起作用,当我通过昵称 = @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

有什么建议吗?

4

3 回答 3

2

您可以判断关联是否加载了loaded?.

如果我理解您的问题,这里发生的事情是您正试图在 ActiveRecord::Relation 上运行查找器。快速浏览代码,它似乎不会在发出查询之前尝试查看是否加载了集合。但是,它确实采用了一个可以避免多个查询的块。例如(模型名称已更改,因为我正在使用为另一个问题创建的示例项目):

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">]
于 2012-12-17T20:50:47.143 回答
0

也许是这样的:

@argument.includes(:comments => [{ :user => :nicknames }])

不过没试过。。。

于 2012-12-17T20:13:11.123 回答
0

您可以尝试这样的方法来包含多个表格

 User.find(:all, :include => Room.find(:all,:include => :review))
于 2014-06-06T06:25:44.787 回答