我想知道是否有人可以解释如何在一组对象上使用will_paginate?
例如,在我的网站上,我有一个意见部分,用户可以对意见进行评分。这是我写的一个方法来收集评价意见的用户:
def agree_list
list = OpinionRating.find_all_by_opinion_id(params[:id])
@agree_list = []
list.each do |r|
user = Profile.find(r.profile_id)
@agree_list << user
end
end
谢谢
答案 0 :(得分:211)
will_paginate 3.0旨在利用Rails 3中的新ActiveRecord::Relation
,因此默认情况下仅对关系定义paginate
。它仍然可以使用数组,但你必须告诉rails要求该部分。
在config/initializers
(我使用will_paginate_array_fix.rb
)的文件中,添加此
require 'will_paginate/array'
然后你可以在数组上使用
my_array.paginate(:page => x, :per_page => y)
答案 1 :(得分:9)
您可以使用Array#from
来模拟分页,但这里真正的问题是您根本不应该使用Array
。
这是 ActiveRecord Associations 的用途。您应该仔细阅读该指南,如果您正在开发Rails应用程序,则需要了解许多有用的内容。
让我告诉你一个更好的方法来做同样的事情:
class Profile < ActiveRecord::Base
has_many :opinion_ratings
has_many :opinions, :through => :opinion_ratings
end
class Opinion < ActiveRecord::Base
has_many :opinion_ratings
end
class OpinionRating < ActiveRecord::Base
belongs_to :opinion
belongs_to :profile
end
重要的是,您的数据库架构遵循正确的命名约定或所有这些都将中断。确保您使用 Database Migrations 创建表格,而不是手动执行。
这些关联将在您的模型上创建帮助程序,以便更轻松地进行搜索。您可以使用named_scope
或scope
使Rails为您执行此操作,而不是迭代OpinionRating列表并手动收集用户,具体取决于您使用的是Rails 2.3还是3.0。既然你没有指定,我会举两个例子。将其添加到您的OpinionRating类:
<强> 2.3 强>
named_scope :for, lambda {|id|
{
:joins => :opinion,
:conditions => {
:opinion => { :id => id }
}
}
}
named_scope :agreed, :conditions => { :agree => true }
named_scope :with_profiles, :includes => :profile
<强> 3.0 强>
scope :agreed, where(:agree => true)
def self.for(id)
joins(:opinion).where(:opinion => { :id => id })
end
在任何一种情况下,您都可以在for(id)
模型上调用OpinionRatings
并将其传递给ID:
<强> 2.3 强>
@ratings = OpinionRating.agreed.for(params[:id]).with_profiles
@profiles = @ratings.collect(&:profile)
<强> 3.0 强>
@ratings = OpinionRating.agreed.for(params[:id]).includes(:profile)
@profiles = @ratings.collect(&:profile)
所有这一切的结果是你现在可以轻松地分页:
@ratings = @ratings.paginate(:page => params[:page])
Rails 4.x的更新:或多或少相同:
scope :agreed, ->{ where agreed: true }
def self.for(id)
joins(:opinion).where(opinion: { id: id })
end
虽然对于较新的Rails,我的首选是kaminari分页:
@ratings = @ratings.page(params[:page])
答案 2 :(得分:4)
gem will_paginate
将对ActiveRecord查询和数组进行分页。
list = OpinionRating.where(:opinion_id => params[:id]).includes(:profile).paginate(:page => params[:page])
@agree_list = list.map(&:profile)
答案 3 :(得分:1)
如果您不想使用配置文件或遇到问题,您还可以确保返回ActiveRecord :: Relation而不是数组。例如,将agree_list更改为用户ID列表,然后对这些ID执行IN以返回Relation。
def agree_list
list = OpinionRating.find_all_by_opinion_id(params[:id])
@agree_id_list = []
list.each do |r|
user = Profile.find(r.profile_id)
@agree_id_list << user.id
end
@agree_list = User.where(:id => @agree_id_list)
end
从数据库角度来看,这是低效的,但对于任何遇到will_paginate配置文件问题的人来说,它都是一个选项。
答案 4 :(得分:0)
我利用了rails关联,并提出了一种新方法:
def agree_list
o = Opinion.find(params[:id])
@agree_list = o.opinion_ratings(:conditions => {:agree => true}, :order => 'created_at DESC').paginate :page => params[:page]
rescue ActiveRecord::RecordNotFound
redirect_to(profile_opinion_path(session[:user]))
end
在我看来,我像这样查看了个人资料:
<% @agree_list.each do |rating| %>
<% user = Profile.find(rating.profile_id) %>
<% end %>
如果有更好的方法,请发布。我试图在OpinionRating模型中使用named_scope助手而没有运气。这是我尝试过的一个例子,但不起作用:
named_scope :with_profile, lambda {|id| { :joins => [:profile], :conditions => ['profile_id = ?', id] } }
这看起来和使用find方法一样。
感谢您的帮助。
答案 5 :(得分:0)
我正在使用rails 3 ruby 1.9.2。另外,我刚刚开始使用应用程序,因此不包含css或样式。
安装will_paginate:
gem install will_paginate
添加到Gemfile并运行bundle。
<强>控制器强>
class DashboardController < ApplicationController
include StructHelper
def show
@myData =structHelperGet.paginate(:page => params[:page])
end
end
模块StructHelper查询服务,而不是数据库。 structHelperGet()返回一组记录。
不确定更复杂的解决方案是伪造模型,还是每隔一段时间获取数据并偶尔重新创建一个sqllite表并拥有一个真实的模型来查询。只是创建我的第一个rails应用程序。
查看强>
<div id="Data">
<%= will_paginate @myData%>
<table>
<thead>
<tr>
<th>col 1</th>
<th>Col 2</th>
<th>Col 3</th>
<th>Col 4</th>
</tr>
</thead>
</tbody>
<% @myData.each do |app| %>
<tr>
<td><%=app[:col1]%> </td>
<td><%=app[:col2]%> </td>
<td><%=app[:col3]%> </td>
<td><%=app[:col4]%> </td>
</tr>
<% end %>
</tbody>
</table>
<%= will_paginate @myData%>
</div>
这将为您提供每页默认30行的分页。
如果您尚未阅读http://railstutorial.org,请立即开始阅读。
答案 6 :(得分:0)
即使没有任何宝石,也可以实现分页。我看到了这个How do I paginate an Array?。 kaminari gems文档中的简单实现。请参阅以下我从kaminari gems doc中获取的示例
var food = "pizza.png"
food_icon.setImageResource(R.drawable.food)//image is the pizza
food = "burger.png"
food_icon.setImageResource(R.drawable.food)//image is the burger