will_paginate返回多个重复项

时间:2018-10-29 18:24:25

标签: ruby-on-rails will-paginate

will_paginate疯了。我要求它返回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]]

任何想法导致这种大规模重复吗?我已经在Google上进行了搜索,但只找到一个问题的答案,该问题在一页的底部和另一页的顶部重复,而在这里不是这种情况。

谢谢!

编辑:从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>

2 个答案:

答案 0 :(得分:0)

首先,您可能真的不想像您一样使用字符串插值创建查询。如果这是一个暴露于互联网的应用程序,那么坏人可以将他们想要的内容注入该查询中。请参阅此处的“不安全”警告以及如何在查询中使用?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)

答案 1 :(得分:0)

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

这里:

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

您要遍历@properties,并在每次迭代时呈现@properties的集合。假设@properties有12个元素,那么它将为您提供12乘以12个属性= 144。

要修复此问题,只需将该循环替换为

<%= render @properties %>

这是<%= render partial: 'property', collection: @properties %>的简写。它将仅使您的收藏一次。

https://guides.rubyonrails.org/layouts_and_rendering.html#rendering-collections上查看详细信息