6

Sau một chút tìm kiếm, tôi vẫn bị mất một chút. Có một vài câu hỏi tương tự khác ở đó có liên quan đến việc phân trang nhiều mô hình, nhưng chúng không được trả lời hoặc chúng trích xuất riêng từng mô hình.cách phân trang các bản ghi từ nhiều mô hình? (Tôi có cần một sự kết hợp đa hình không?)

Tôi cần phải phân trang tất cả hồ sơ của Tài khoản cùng một lúc.

class Account 
    :has_many :emails 
    :has_many :tasks 
    :has_many :notes 
end 

Vì vậy, tôi muốn tìm 30 "điều" gần đây nhất cho dù chúng là gì. Điều này thậm chí có thể với các giải pháp phân trang hiện tại không?

Giống như sử dụng kết hợp tải mong muốn và Kaminari hoặc will_paginate?


Hoặc, trước tiên tôi nên thiết lập một sự kết hợp đa hình của tất cả những thứ này, được gọi là Mục. Sau đó, phân trang 30 mục gần đây nhất, sau đó thực hiện tra cứu các bản ghi liên quan của các mục đó.

Và nếu có, tôi không thực sự chắc chắn mã đó sẽ trông như thế nào. Bất kỳ đề xuất?


Cách nào tốt hơn? (hoặc thậm chí có thể)

Đường ray 3.1, Ruby 1.9.2, ứng dụng không có trong sản xuất.

+0

Sử dụng will_paginate, th sẽ giúp: http://stackoverflow.com/questions/1465949/how-to-use-will-paginate-with-a-nested-resource-in-rails –

+0

Cảm ơn bạn. Nhưng, đó không phải là những gì tôi đang tìm kiếm. – GoodGets

+0

Hãy suy nghĩ "phân trang qua một tập hợp các hàng dữ liệu" thay vì phân trang qua nhiều hàng của một bảng cơ sở dữ liệu có thể hữu ích. Nó không quan trọng có bao nhiêu mô hình dữ liệu đến từ. Bạn cũng có thể xem kaminiri để xem liệu nó có đáp ứng tốt hơn nhu cầu của bạn hay không. –

Trả lời

1

Tốt câu hỏi ... Tôi không chắc chắn về một giải pháp "tốt", nhưng bạn có thể làm một hacky trong ruby:

Bạn sẽ cần phải đầu tiên lấy ra 30 mới nhất của từng loại "điều", và đặt chúng vào một mảng, lập chỉ mục bởi created_at, sau đó sắp xếp rằng mảng bởi created_at và lấy top 30.

một điểm hoàn toàn phi refactored bắt đầu có thể là một cái gì đó như:

emails = Account.emails.all(:limit => 30, :order => :created_at) 
tasks = Account.tasks.all(:limit => 30, :order => :created_at) 
notes = Account.notes.all(:limit => 30, :order => :created_at) 
thing_array = (emails + tasks + notes).map {|thing| [thing.created_at, thing] } 
# sort by the first item of each array (== the date) 
thing_array_sorted = thing_array.sort_by {|a,b| a[0] <=> b[0] } 
# then just grab the top thirty 
things_to_show = thing_array_sorted.slice(0,30) 

Note : không được kiểm tra, có thể đầy lỗi ...;)

+0

Cảm ơn bạn đã trả lời. Tuy nhiên, đó sẽ là quá khủng khiếp không hiệu quả, phải lấy thêm 60 hồ sơ mỗi lần. Sau đó phải theo dõi xem có bao nhiêu trong số đó được trình bày. Ngoài ra, bạn things_array có thể được refactored để một cái gì đó như: '(email + nhiệm vụ + ghi chú) .sort_by (&: updated_at) .take (30)' – GoodGets

+0

cần phải đảo ngược để có được gần đây nhất: '(email + nhiệm vụ + ghi chú) .sort_by (&: updated_at) .reverse.take (30) ' – GoodGets

+0

Đúng - chắc chắn không hiệu quả ... như tôi đã nói - chỉ là một giải pháp hacky :) –

2

với will_paginate:

@records = #do your work and fetch array of records you want to paginate (various types) 

sau đó làm như sau:

current_page = params[:page] || 1 
per_page = 10 
@records = WillPaginate::Collection.create(current_page, per_page, records.size) do |pager| 
pager.replace(@records) 
end 

sau đó theo quan điểm của bạn:

<%=will_paginate @records%> 
0
emails = account.emails 
tasks = account.tasks 
notes = account.notes 

@records = [emails + tasks + notes].flatten.sort_by(&:updated_at).reverse 

@records = WillPaginate::Collection.create(params[:page] || 1, 30, @records.size) do |pager| 
    pager.replace(@records) 
end 

Thats nó ... :)