简体   繁体   English

将will_paginate与多个模型一起使用(Rails)

[英]Using will_paginate with multiple models (Rails)

Pretty sure that I'm missing something really simple here: 很确定我在这里遗漏了一些非常简单的东西:

I'm trying to display a series of pages that contain instances of two different models - Profiles and Groups. 我正在尝试显示一系列包含两个不同模型实例的页面 - 配置文件和组。 I need them ordering by their name attribute. 我需要按名称属性排序。 I could select all of the instances for each model, then sort and paginate them, but this feels sloppy and inefficient. 我可以为每个模型选择所有实例,然后对它们进行排序和分页,但这感觉很邋and且效率低下。

I'm using mislav-will_paginate, and was wondering if there is any better way of achieving this? 我正在使用mislav-will_paginate,并想知道是否有更好的方法来实现这一目标? Something like: 就像是:

[Profile, Group].paginate(...)

would be ideal! 会是理想的!

Good question, I ran into the same problem a couple of times. 好问题,我遇到过几次相同的问题。 Each time, I ended it up by writing my own sql query based on sql unions (it works fine with sqlite and mysql). 每次,我通过编写基于sql联合的自己的sql查询来结束它(它与sqlite和mysql一起正常工作)。 Then, you may use will paginate by passing the results ( http://www.pathf.com/blogs/2008/06/how-to-use-will_paginate-with-non-activerecord-collectionarray/ ). 然后,您可以通过传递结果来使用will paginate( http://www.pathf.com/blogs/2008/06/how-to-use-will_paginate-with-non-activerecord-collectionarray/ )。 Do not forget to perform the query to count all the rows. 不要忘记执行查询来计算所有行。

Some lines of code (not tested) 一些代码行(未经测试)

my_query = "(select posts.title from posts) UNIONS (select profiles.name from profiles)"
total_entries = ActiveRecord::Base.connection.execute("select count(*) as count from (#{my_query})").first['count'].to_i

results = ActiveRecord::Base.connection.select_rows("select * from (#{my_query}) limit #{limit} offset #{offset}")

Is it overkilled ? 它是否过度使用? Maybe but you've got the minimal number of queries and results are consistent. 也许,但你得到的查询数量最少,结果也是一致的。

Hope it helps. 希望能帮助到你。

Note: If you get the offset value from a http param, you should use sanitize_sql_for_conditions (ie: sql injection ....) 注意:如果从http参数获得偏移值,则应使用sanitize_sql_for_conditions(即:sql injection ....)

You can get close doing something like: 你可以近距离做一些事情:

@profiles, @groups = [Profile, Group].map do |clazz|
  clazz.paginate(:page => params[clazz.to_s.downcase + "_page"], :order => 'name')
end

That will then paginate using page parameters profile_page and group_page . 然后,将使用页面参数profile_pagegroup_page进行分页。 You can get the will_paginate call in the view to use the correct page using: 您可以在视图中获取will_paginate调用以使用正确的页面:

<%= will_paginate @profiles, :page_param => 'profile_page' %>
....
<%= will_paginate @groups, :page_param => 'group_page' %>

Still, I'm not sure there's a huge benefit over setting up @groups and @profiles individually. 尽管如此,我不确定单独设置@groups@profiles有什么好处。

in my last project i stuck into a problem, i had to paginate multiple models with single pagination in my search functionality. 在我的上一个项目中我遇到了一个问题,我不得不在我的搜索功能中对单个分页的多个模型进行分页。 it should work in a way that the first model should appear first when the results of the first model a second model should continue the results and the third and so on as one single search feed, just like facebook feeds. 它应该以第一个模型应该首先出现的方式工作,第一个模型的结果第二个模型应该继续结果而第三个等等作为一个单一的搜索提要,就像facebook提要一样。 this is the function i created to do this functionality 这是我创建的用于执行此功能的功能

def multi_paginate(models, page, per_page)

  WillPaginate::Collection.create(page, per_page) do |pager|

    # set total entries
    pager.total_entries = 0
    counts = [0]
    offsets = []
    for model in models
          pager.total_entries += model.count
          counts << model.count
          offset = pager.offset-(offsets[-1] || 0)
          offset = offset>model.count ? model.count : offset 
          offsets << (offset<0 ? 0 : offset)
    end

    result = []
    for i in 0...models.count
          result += models[i].limit(pager.per_page-result.length).offset(offsets[i]).to_a
    end

    pager.replace(result)
  end

end

try it and let me know if you have any problem with it, i also posted it as an issue to will_paginate repository, if everyone confirmed that it works correctly i'll fork and commit it to the library. 尝试它,让我知道如果你有任何问题,我也将它作为一个问题发布到will_paginate存储库,如果每个人都确认它正常工作我将fork并将其提交到库。 https://github.com/mislav/will_paginate/issues/351 https://github.com/mislav/will_paginate/issues/351

Have you tried displaying two different sets of results with their own paginators and update them via AJAX? 您是否尝试使用自己的分页器显示两组不同的结果并通过AJAX更新它们? It is not exactly what you want, but the result is similar. 这不完全是你想要的,但结果是相似的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM