如何从多个模型中分页记录? (我需要多态连接吗?)

时间:2011-10-31 18:06:23

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 will-paginate kaminari

经过相当多的搜索,我仍然有点迷失。还有一些其他类似的问题涉及对多个模型进行分页,但它们要么没有答案,要么单独讨价还价。

我需要立即对帐户的所有记录进行分页。

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,app尚未投入使用。

3 个答案:

答案 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%>

答案 1 :(得分:1)

好问题......我不确定一个“好”的解决方案,但你可以在ruby中做一个hacky:

你需要首先获取每种类型的“东西”中最新的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)

注意:未经测试,可能充满了错误......;)

答案 2 :(得分: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

多数民众赞成......:)