will_paginate 返回多个重复项

will_paginate returning multiple duplicates

will_paginate 快疯了。我要求它 return 12 行,它在一个页面上复制了 12 12 次,给我 12 组重复项和一个页面上总共 144 行。

我的控制器代码:

  query = "address1 LIKE \"%#{params[:filter]}%\""
  @properties = Property.where(query).group("id").paginate(page: params[:page], per_page: 12)

起初,日志文件显示如下:

Processing by PropertiesController#index as HTML
  Parameters: {"utf8"=>"✓", "filter"=>"Acacia", "commit"=>"Filter"}
  Rendering properties/index.html.erb within layouts/application
  Rendered layouts/_header.html.erb (2.2ms)
   (34.7ms)  SELECT COUNT(*) AS count_all, `property`.`id` AS property_id FROM `property` WHERE (address1 LIKE "%Acacia%") GROUP BY `property`.`id`
  Property Load (34.9ms)  SELECT  `property`.* FROM `property` WHERE (address1 LIKE "%Acacia%") GROUP BY `property`.`id` LIMIT 12 OFFSET 0
  Photo Load (34.5ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10001 LIMIT 1
  Photo Load (34.8ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10002 LIMIT 1
  Photo Load (34.4ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10003 LIMIT 1
  Photo Load (34.4ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10004 LIMIT 1
  Photo Load (34.5ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10005 LIMIT 1
  Photo Load (34.3ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10006 LIMIT 1
  Photo Load (34.6ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10007 LIMIT 1
  Photo Load (35.7ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10008 LIMIT 1
  Photo Load (34.6ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10009 LIMIT 1
  Photo Load (34.6ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10010 LIMIT 1
  Photo Load (34.6ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10011 LIMIT 1
  Photo Load (39.3ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10012 LIMIT 1

然后再显示 11 次:

  Rendered collection of properties/_property.html.erb [12 times] (467.1ms)
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10001 LIMIT 1  [["propid", 10001], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10002 LIMIT 1  [["propid", 10002], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10003 LIMIT 1  [["propid", 10003], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10004 LIMIT 1  [["propid", 10004], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10005 LIMIT 1  [["propid", 10005], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10006 LIMIT 1  [["propid", 10006], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10007 LIMIT 1  [["propid", 10007], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10008 LIMIT 1  [["propid", 10008], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10009 LIMIT 1  [["propid", 10009], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10010 LIMIT 1  [["propid", 10010], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10011 LIMIT 1  [["propid", 10011], ["LIMIT", 1]]
  CACHE (0.0ms)  SELECT  `photos`.* FROM `photos` WHERE `photos`.`propid` = 10012 LIMIT 1  [["propid", 10012], ["LIMIT", 1]]

知道是什么导致了这种大规模复制吗?我用谷歌搜索,只找到了一个页面底部和另一页顶部重复的单个项目的答案,而这里不是这种情况。

谢谢!

编辑:从 will_paginate 切换到 Kaminari,我仍然遇到同样的问题。来自控制器的 Kaminari 代码:

@properties = Property.where(query).page(params[:page]).per(12)

查看:

<% provide(:title, 'All Properties') %>

<%= render "layouts/header" %>

<div class="text-center top-padding-to-miss-navbar">
  <h1>All Properties</h1>
</div>

<div id="pi-filter">
  <%= form_tag '', :method => :get do %>
    <%= text_field('', :filter, :value => params[:filter]) %>
    <%= submit_tag 'Filter' %>
  <% end %>
</div>

<div id="pi-create-new-property-link">
  <%= link_to "Create New Property", property_new_path %>
</div>

<div class="ui-left-margin">
  <%= will_paginate %>
</div>

<div id="ui-padded-sides">
  <ul class="properties">
    <% @properties.each do %>
      <%= render @properties %>
    <% end %>
  </ul>
</div>

<div class="ui-left-margin">
  <%= will_paginate %>
</div>

部分被视图使用:

<li>
  <%= link_to property.address1, property %>
  <%= link_to "| Edit" , property_edit_path(property) %>
  <%= link_to "| Delete", property, method: :delete,
      data: { confirm: "Are you sure you want to delete this property?" } %>
</li>

首先,您可能真的不想像现在这样创建带有字符串插值的查询。如果这是一个暴露在互联网上的应用程序,坏人就可以将他们想要的任何东西注入到该查询中。请参阅此处的 "unsafe" 警告以及如何在查询中使用 ?https://guides.rubyonrails.org/active_record_querying.html#pure-string-conditions

至于是什么原因造成的,我认为可能是因为使用了 "group(id)" 子句。你没有在 id 周围聚合任何东西。所以查询应该是:

@properties = Property.where(query).paginate(page: params[:page], per_page: 12)

感谢更新。现在很清楚问题出在哪里了。

这里:

<% @properties.each do %>
  <%= render @properties %>
<% end %>

您正在迭代 @properties,并且在每次迭代中渲染 @properties 的 collection。假设 @properties 有 12 个元素,它给你 12 乘以 12 个属性 = 144.

要修复它只需将循环替换为

<%= render @properties %>

这是 <%= render partial: 'property', collection: @properties %> 的 shorthand。它只会渲染您的 collection 一次。

详情见https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-collections