Ruby on Rails会为数组分配一个数组
我想知道是否有人可以解释如何使用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
谢谢
will_paginate 3.0被devise为利用Rails 3中新的ActiveRecord::Relation
,所以它只在关系上定义paginate
。 它仍然可以和一个数组一起工作,但是你必须告诉rails需要这个部分。
在config/initializers
文件config/initializers
(我用will_paginate_array_fix.rb
),添加这个
require 'will_paginate/array'
然后你可以在数组上使用
my_array.paginate(:page => x, :per_page => y)
你可以使用Array#from
来模拟分页,但这里真正的问题是你根本不应该使用Array
。
这是ActiveRecord协会所做的。 您应该仔细阅读该指南,如果您正在开发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
数据库模式遵循适当的命名约定或所有这些都将中断是很重要的。 确保你正在使用数据库迁移创build你的表格,而不是手工完成。
这些关联会在您的模型上创build助手,使search更容易。 而不是迭代OpinionRatings列表并手动收集用户,您可以使用Rails 2.3或3.0,使用named_scope
或scope
来让Rails执行此操作。 既然你没有指定,我会举两个例子。 添加到您的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
无论哪种情况,您都可以在OpinionRatings
模型上调用for(id)
并将其传递给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:或多或less相同:
scope :agreed, ->{ where agreed: true } def self.for(id) joins(:opinion).where(opinion: { id: id }) end
虽然对于较新的Rails,我的首选是kaminari分页:
@ratings = @ratings.page(params[:page])
gem will_paginate
将分页ActiveRecord查询和数组。
list = OpinionRating.where(:opinion_id => params[:id]).includes(:profile).paginate(:page => params[:page]) @agree_list = list.map(&:profile)
如果你不想使用configuration文件或者遇到麻烦,你也可以确保你返回一个ActiveRecord :: Relation而不是一个数组。 例如,将agree_list更改为用户标识列表,然后对这些标识执行IN以返回关系。
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
从数据库的angular度来看,这是低效的,但对于任何有关will_paginateconfiguration文件的问题,这是一个选项。
我利用了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
在我看来,我看起来像这样的configuration文件:
<% @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方法相同。
感谢所有的帮助。
我使用rails 3 ruby 1.9.2。 另外,我刚开始的应用程序,所以没有CSS或样式包括在内。
安装will_paginate:
gem install will_paginate
添加到Gemfile并运行捆绑。
调节器
class DashboardController < ApplicationController include StructHelper def show @myData =structHelperGet.paginate(:page => params[:page]) end end
模块StructHelper查询服务,而不是数据库。 structHelperGet()返回logging数组。
不知道是否更复杂的解决scheme是伪造一个模型,或者每隔一段时间抓取数据,偶尔重新创build一个sqllite表,并有一个真正的模型来查询。 只是创build我的第一个轨道应用程序。
视图
<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 ,现在开始阅读。