6

经过相当多的搜索后,我仍然有点失落。还有一些类似的问题涉及到对多个模型进行分页处理,但是它们要么没有答案,要么分别讨论每个模型。如何分页来自多个模型的记录? (我是否需要一个多态连接?)

我需要一次对一个帐户的所有记录进行分页。

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

所以,我想找到最近的30个“事物”,不管它们是什么。这在目前的分页解决方案中甚至可能吗?

像使用渴望加载和Kaminari或will_paginate的某种组合?或者,我应该首先设置所有这些东西的多态连接,称为Items。然后分页最近的30个项目,然后查找这些项目的关联记录。

如果是这样,我不确定代码应该是什么样子。有什么建议么?


哪种方式更好? (或者甚至可能)

Rails 3.1,Ruby 1.9.2,应用程序没有生产。

+0

使用will_paginate,th是应该帮助:http://stackoverflow.com/questions/1465949/how-to-use-will-paginate-with-a-nested-resource-in-rails –

+0

谢谢。但是,那不是我想要的。 – GoodGets

+0

认为“通过一组数据行进行分页”而不是分页浏览一个数据库表的多行可能会有所帮助。数据来自多少模型无关紧要。你也可以看看kaminiri,看看它是否更好地满足你的需求。 –

回答

1

好问题......我不知道一个“好”的解决方案,但你可以做一个哈克之一红宝石:

你需要首先提取出30最新每种类型的“东西”,并把它们放到一个数组,由created_at索引,则排序created_at数组,并采取前30

一个完全非重构的开始可能是这样的:

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) 

注:未经测试,可能会充满bug ...;)

+0

谢谢你的回复。但是,这太不可靠了,每次都需要获取60条额外的记录。然后不得不跟踪每一个展示的数量。此外,您可以将things_array重构为如下形式: '(电子邮件+任务+笔记).sort_by(&:updated_at).take(30)' – GoodGets

+0

需要反转以获取最新信息: '笔记).sort_by(&:updated_at).reverse.take(30)' – GoodGets

+0

是的 - 绝对不行的...正如我所说 - 只是一个哈克解决方案:) –

2

与will_paginate:

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

然后执行以下操作:

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

然后在您的视图:

<%=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 

完蛋了... :)

相关问题