【问题标题】:ActiveRecord joins on two models with will_paginate not working to get unique many-to-many relations?ActiveRecord 加入了两个模型,而 will_paginate 无法获得独特的多对多关系?
【发布时间】:2014-12-27 22:47:54
【问题描述】:

在我的 Rails 4 应用程序中,我的博客和类别之间存在多对多关系,其中包含一个 has_many :through => 连接表。

我正在使用 gem will_paginate 对博客文章的页面进行分页。

但是,对于每一页,我想显示与每页显示的每篇博文相关的独特类别。目前我有一个类似的查询:

Category.joins(:blogs).paginate(page: params[:page], per_page: 20).uniq

这对第一页很有效,但对于第二页,当 params[:page] == 2 时,结果是一组空的类别,即使第二页包含带有类别的博客文章。

我该如何解决这个问题?

编辑:

行动:

  def home
    @categories = Category.joins(:blogs).paginate(page: params[:page], per_page: 20).uniq
    @blogs = Blog.paginate(page: params[:page], per_page: 20)
    respond_to do |format|
      format.html
    end
  end

部分显示类别:

<ul class="filter">
        <li><a class="active" href="" data-filter="*">All</a></li>
        <% @categories.each do |category| %>
            <li><a href="#" data-filter=".<%= category.title.downcase unless nil %>"><%= category.title unless nil  %></a></li>
        <% end %>
 </ul>

与操作中填充的博客和类别的集合相比,这里的部分逻辑不太相关。

【问题讨论】:

  • 我认为您在博客中使用的类别少于 20 个,不是吗?
  • 该参数只是指定每页需要多少个,当没有 20 个时它只返回最后一页的剩余部分。
  • 是的,因为我认为您的查询必须有效。你在控制台测试过吗?第 1 页和第 2 页。
  • 是的,很多次。它非常适合页面:1 但不是 2
  • 在控制台运行这个:Categories.joins(:blogs).sizeCategories.joins(:blogs).uniq.size

标签: ruby-on-rails ruby join activerecord will-paginate


【解决方案1】:

如果我理解了这个问题:您正试图以不重复的方式显示博客及其类别。

那么你可以这样做:

blogs = Blog.includes(:categories).paginate(page: params[:page], per_page: 20)

没有理由显示一个类别超过 1 次,除非你复制了关系,但你必须防止这种情况发生。

如果你这样做:

 @categories = Category.joins(:blogs).paginate(page: params[:page], per_page: 20)

您获得了多达 20 条类别记录。他们每个人,以及它的所有博客。

您不能这样做:@blogs = Blog.paginate(page: params[:page], per_page: 20),因为您不能使用与@categories 相同的params[:page] 进行分页,并且您将博客数据附加到每个类别。

只需设置@categoríes,您就可以在自己的视图中进行操作:

<% @categories.each do |category| %>
  <%= "#{category.name} has #{category.blogs.size} blogs" %>
  <% category.blogs.each do |blog|>
    <%= blog.author %>
  <% end %>
<% end %>

而且您根本不需要实例变量@blogs。

编辑:通过私人聊天揭示答案:

categories = []
blogs.each do |b|
   categories.push(*b.categories)
end
categories.uniq

【讨论】:

  • 我希望用它的博客来显示类别而不重复。所以 Category.includes(:blogs).paginate(page: 2, per_page 20) 不起作用,即使第二页确实包含具有类别的博客,它仍然产生 0
  • 我基本上有一个 javascript 过滤器,并且对于每个分页页面,我打印出一个类别列表,我希望它是属于 Blog.paginate(page: 2, per_page: 20),因为它适用于第 1 页,但不适用于第 2 页
  • 您可以编辑问题并为操作添加视图和部分内容吗?
  • 好的,请参考上面。
【解决方案2】:

如果您的数据库支持它,一种选择是使用子查询。所以:

Category
  .all
  .select("categories.*, (select count(blogs.id) from blogs where blogs.category_id = categories.id) as number_of_blogs")
  .paginate(page: params[:page], per_page: 20)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 2010-10-12
    • 1970-01-01
    • 2014-07-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多