Ruby on Rails will_paginate 一个数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4352895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:48:21  来源:igfitidea点击:

Ruby on Rails will_paginate an array

ruby-on-railspaginationwill-paginate

提问by Brian

I was wondering if someone could explain how to use will_paginateon an array of objects?

我想知道是否有人可以解释如何在对象数组上使用will_paginate

For example, on my site I have an opinion section where users can rate the opinions. Here's a method I wrote to gather the users who have rated the opinion:

例如,在我的网站上,我有一个意见部分,用户可以在其中对意见进行评分。这是我编写的一种方法,用于收集对意见进行评分的用户:

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

Thank you

谢谢

回答by keithepley

will_paginate3.0 is designed to take advantage of the new ActiveRecord::Relationin Rails 3, so it defines paginateonly on relations by default. It can still work with an array, but you have to tell rails to require that part.

will_paginate3.0 旨在利用ActiveRecord::RelationRails 3中的新功能,因此paginate默认情况下它仅定义关系。它仍然可以使用数组,但您必须告诉 rails 需要该部分。

In a file in your config/initializers(I used will_paginate_array_fix.rb), add this

在你config/initializers(我用过will_paginate_array_fix.rb)的文件中,添加这个

require 'will_paginate/array'

Then you can use on arrays

然后你可以在数组上使用

my_array.paginate(:page => x, :per_page => y)

回答by Adam Lassek

You could use Array#fromto simulate pagination, but the real problem here is that you shouldn't be using Arrayat all.

你可以Array#from用来模拟分页,但这里真正的问题是你根本不应该使用Array

This is what ActiveRecord Associationsare made for. You should read that guide carefully, there is a lot of useful stuff you will need to know if you're developing Rails applications.

这就是ActiveRecord 关联的用途。您应该仔细阅读该指南,如果您正在开发 Rails 应用程序,您需要了解很多有用的内容。

Let me show you a better way of doing the same thing:

让我向您展示一个更好的方法来做同样的事情:

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

It's important that your database schema is following the proper naming conventions or all this will break. Make sure you're creating your tables with Database Migrationsinstead of doing it by hand.

重要的是您的数据库架构遵循正确的命名约定,否则所有这些都会中断。确保您使用数据库迁移创建表,而不是手动创建。

These associations will create helpers on your models to make searching much easier. Instead of iterating a list of OpinionRatings and collecting the users manually, you can make Rails do this for you with the use of named_scopeor scopedepending on whether you're using Rails 2.3 or 3.0. Since you didn't specify, I'll give both examples. Add this to your OpinionRating class:

这些关联将在您的模型上创建帮助程序,使搜索变得更加容易。您可以使用 Railsnamed_scopescope根据您使用的是 Rails 2.3 还是 3.0 ,让 Rails 为您执行此操作,而不是迭代 OpinionRatings 列表并手动收集用户。由于您没有指定,我将给出两个示例。将此添加到您的 OpinionRating 类中:

2.3

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

3.0

scope :agreed, where(:agree => true)

def self.for(id)
  joins(:opinion).where(:opinion => { :id => id })
end

In either case you can call for(id)on the OpinionRatingsmodel and pass it an id:

在这两种情况下,你可以调用for(id)OpinionRatings模型,并把它传递一个id:

2.3

2.3

@ratings = OpinionRating.agreed.for(params[:id]).with_profiles
@profiles = @ratings.collect(&:profile)

3.0

3.0

@ratings = OpinionRating.agreed.for(params[:id]).includes(:profile)
@profiles = @ratings.collect(&:profile)

The upshot of all this is that you can now easily paginate:

所有这一切的结果是,您现在可以轻松地进行分页:

@ratings = @ratings.paginate(:page => params[:page])


Update for Rails 4.x: more or less the same:

Rails 4.x 更新:大致相同:

scope :agreed, ->{ where agreed: true }

def self.for(id)
  joins(:opinion).where(opinion: { id: id })
end 

Although for newer Rails my preference is kaminarifor pagination:

尽管对于较新的 Rails,我更喜欢使用kaminari进行分页:

@ratings = @ratings.page(params[:page])

回答by iain

The gem will_paginatewill paginate both ActiveRecord queries and arrays.

gemwill_paginate将对 ActiveRecord 查询和数组进行分页。

list = OpinionRating.where(:opinion_id => params[:id]).includes(:profile).paginate(:page => params[:page])
@agree_list = list.map(&:profile)

回答by mcclaskc

If you don't want to use the config file or are having trouble with it, you can also just ensure you return an ActiveRecord::Relation instead of an array. For instance, change the agree_list to be a list of user ids instead, then do an IN on those ids to return a Relation.

如果您不想使用配置文件或遇到问题,您也可以确保返回 ActiveRecord::Relation 而不是数组。例如,将同意列表改为用户 ID 列表,然后对这些 ID 执行 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

This is inefficient from a database perspective, but it's an option for anybody having issues with the will_paginate config file.

从数据库的角度来看,这是低效的,但对于任何对 will_paginate 配置文件有问题的人来说,这是一个选择。

回答by Jose Kj

You can implement pagination even without any gem.I saw this How do I paginate an Array?. Simple implementation in kaminari gems doc. Please see the below example which i got from kaminari gems doc

即使没有任何 gem,您也可以实现分页。看到了这个如何对数组进行分页?. kaminari gems 文档中的简单实现。请参阅我从 kaminari gems doc 获得的以下示例

arr = (1..100).to_a
page, per_page = 1, 10
arr[((page - 1) * per_page)...(page * per_page)] #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
page, per_page = 2, 10
arr[((page - 1) * per_page)...(page * per_page)] #=> [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

回答by Brian

I took advantage of rails associations, and came up with a new method:

我利用了 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

In my view I looked up the profile like so:

在我看来,我像这样查找了个人资料:

<% @agree_list.each do |rating| %>
  <% user = Profile.find(rating.profile_id) %>
<% end %>

Please post up if there's a better way to do this. I tried to use the named_scope helper in the OpinionRating model with no luck. Here's an example of what I tried, but doesn't work:

如果有更好的方法来做到这一点,请张贴。我尝试在 OpinionRating 模型中使用 named_scope 助手,但没有成功。这是我尝试过但不起作用的示例:

named_scope :with_profile, lambda {|id| { :joins => [:profile], :conditions => ['profile_id = ?', id] } }

That seemed like the same as using the find method though.

不过,这似乎与使用 find 方法相同。

Thanks for all the help.

感谢所有的帮助。

回答by mpechner

I am using rails 3 ruby 1.9.2. Also, I am just starting app, so no css or styles included.

我正在使用 rails 3 ruby​​ 1.9.2。另外,我刚刚启动应用程序,因此不包含 css 或样式。

Install will_paginate:

安装 will_paginate:

gem install will_paginate

gem install will_paginate

Add to Gemfile and run bundle.

添加到 Gemfile 并运行 bundle。

Controller

控制器

class DashboardController < ApplicationController
    include StructHelper

    def show
        @myData =structHelperGet.paginate(:page => params[:page])
    end

end

module StructHelper queries a service, not a database. structHelperGet() returns an array of records.

模块 StructHelper 查询服务,而不是数据库。structHelperGet() 返回一个记录数组。

Not sure if a more sophisticated solution would be to fake a model, or to grab the data every so often and recreate a sqllite table once in a while and have a real model to query. Just creating my first rails app ever.

不确定更复杂的解决方案是伪造模型,还是每隔一段时间抓取数据并偶尔重新创建一个 sqllite 表并有一个真实的模型来查询。刚刚创建了我的第一个 Rails 应用程序。

View

看法

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

This will give you pagnation of the default 30 rows per page.

这将为您提供每页默认 30 行的分页。

If you have not read http://railstutorial.orgyet, start reading it now.

如果您还没有阅读http://railstutorial.org,请立即开始阅读。