5

私は4つのテーブルを持っています:

フィールドを持つ引数

  • ID

とのコメント

  • ID
  • comment_id
  • 引数_id
  • ユーザーID

ユーザー

  • ID

ニックネーム_

  • 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

このようなものを試して、複数のテーブルを含めることができます

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

たぶん次のようなもの:

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

試してないけど…

于 2012-12-17T20:13:11.123 に答える