2011-11-23 26 views
11

cố gắng thực hiện phạm vi trong đường ray3.phạm vi rails3 cho số trẻ em trong mối quan hệ has_many

:book has_many :chapters 

Tôi muốn phạm vi: dài để trả sách với> 10 chương.

Cách tốt nhất để cấu trúc phạm vi này (không sử dụng bộ đệm truy cập)?

cảm ơn!

+0

tại sao không có bộ nhớ cache truy cập? –

+0

Bạn có thể mô tả/đăng bài với cơ sở dữ liệu bạn đang sử dụng không? Tôi tin rằng điều này gây ra một số nhầm lẫn trong các câu trả lời dưới đây –

Trả lời

19

này sẽ giúp bạn đi:

class Book 
    scope :long, joins(:chapters). 
       select('books.id, count(chapters.id) as n_chapters'). 
       group('books.id'). 
       having('n_chapters > 10') 
end 

Liệu nó giúp?

+0

Đây là con đường để đi. Chỉ có vấn đề tôi gặp phải là phương pháp đếm không thực sự hoạt động như mong đợi ở đây. Ví dụ, Book.long.count trả về một băm với số lượng các chương cho mỗi cuốn sách, tôi nghĩ vậy. Bạn phải làm Book.long.all.count. Không quá tệ Tôi đoán –

+3

Điều đó có vẻ đúng nhưng tôi nhận được một lỗi: 'cột' card_count "không tồn tại '(card_count là n_chapters của tôi). Tất cả mọi thứ bởi 'có' dường như hoạt động đúng, và cột card_count chắc chắn là dân cư khi tôi chạy điều này trực tiếp trong một giao diện điều khiển SQL ... –

+0

Tôi không chắc liệu thực hành tốt có liên kết các bài đăng stackoverflow khác hay không. Nhưng tôi có một vấn đề tương tự với bài đăng này nhưng nó chỉ đòi hỏi các thuộc tính nhất định trên các đối tượng has_many. Sẽ thực sự đánh giá cao sự trợ giúp http://stackoverflow.com/questions/31719184/rails-active-record-find-all-records-which-have-a-count-on-has-many-associati –

8

Ah - để trả lời câu hỏi của riêng tôi trong những nhận xét trên, tôi đã phải đặt số lượng trong HAVING:

class Book 
    scope :long, joins(:chapters). 
    select('books.id'). 
    group('books.id'). 
    having('count(chapters.id) > 10') 
end 
1

Trong ray 4.0 phiên bản này hoạt động. Bạn phải đếm() trong mệnh đề có. Có vẻ như có mệnh đề không nhìn thấy 'như n_chapters'.

0

Cách khác là tạo truy vấn phụ. Mặc dù kết nối chính xác hơn (và cũng có thể dẫn đến hiệu năng tốt hơn), nhưng bạn có thể kết thúc với kết quả lạ nếu bạn kết hợp nhiều phạm vi cố gắng tạo nhóm. Truy vấn phụ ít xâm phạm hơn nhiều. Đối với ví dụ này, nó sẽ giống như sau:

class Book 
    scope :with_chapters_count, -> { 
    select('books.*'). 
    select('(select count(chapters.id) from chapters where chapters.book_id = books.id) as chapters_count') 
    } 
    scope :long, -> { 
    with_chapters_count.where("chapters_count > 10") 
    } 
end 
Các vấn đề liên quan