2012-08-28 30 views
5

Tôi có bốn bảng:Rails ActiveRecord nhiều bảng bao gồm

luận với các lĩnh vực

  • id

comments với

  • id
  • comment_id
  • argument_id
  • user_id

người dùng

  • id

nickname với

  • id
  • PROPOSAL_ID
  • user_id
  • tên

mỗi đối số có nhiều ý kiến,

mỗi bình luận thuộc về người dùng,

mỗi người dùng có một cụ thể biệt danh trong đối số.

Khi tôi tìm nạp nhận xét đối số từ DB, tôi cũng muốn bao gồm cả biệt hiệu của từng tác giả.

Câu trả lời là về yêu cầu ActiveRecord Tôi không biết cách viết.

Tôi đã thử với

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

nhưng nó không có vẻ làm việc và khi tôi nhận được nickname qua nickname = @ argument.nicknames.find_by_user_id (comment.user.id) nó thực hiện truy vấn ...

[1m[36mNickname Load (0.6ms)[0m [1mSELECT "nicknames".* FROM "nicknames" WHERE "nicknames"."argument_id" = 59 AND "nicknames"."user_id" = 9 LIMIT 1[0m 

bất kỳ đề xuất nào?

Trả lời

0

Có lẽ cái gì đó như:

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

Chưa thử nó mặc dù ...

2

Bạn có thể biết một hiệp hội được nạp với loaded?.

Điều gì đang xảy ra ở đây, nếu tôi hiểu vấn đề của bạn, đó là bạn đang cố chạy trình tìm kiếm trên ActiveRecord :: Relation. Duyệt nhanh qua the code, nó không xuất hiện mà nó sẽ cố gắng xem nếu một bộ sưu tập được tải trước khi nó phát hành truy vấn. Tuy nhiên, nó có một khối sẽ tránh được nhiều truy vấn. Ví dụ (tên mô hình đã được thay đổi bởi vì tôi đang sử dụng một dự án mẫu tôi đã tạo cho một câu hỏi khác):

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"> 

Bạn thấy trong ví dụ trước rằng ActiveRecord vấn đề truy vấn để tải các hồ sơ liên quan. Điều này là do ActiveRecord đang gọi to_a trên liên kết, buộc toàn bộ cài đặt được tải và sau đó lọc dựa trên các điều kiện chặn. Rõ ràng, đây không phải là lý tưởng.

Hãy thử lại, háo hức tải liên kết.

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"> 

Trong ví dụ cuối cùng ở đây, bạn thấy rằng bộ sưu tập không được tải lại. Thay vào đó, khối được sử dụng để lọc các bản ghi đã tải.

Như bạn thấy dưới đây, ngay cả khi các hồ sơ được nạp, ActiveRecord sẽ phát hành một truy vấn để lấy các kỷ lục liên quan đến:

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">] 
0

Bạn có thể thử một cái gì đó như thế này để bao gồm nhiều hơn một bảng

User.find(:all, :include => Room.find(:all,:include => :review)) 
+2

không tìm thấy (: tất cả) không được chấp nhận? – coorasse

Các vấn đề liên quan