will_paginate возвращает несколько дубликатов - PullRequest
0 голосов
/ 29 октября 2018

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

Есть идеи, что вызывает такое массовое дублирование? Я гуглил и нашел ответы только на один дублирующийся элемент внизу одной страницы и вверху другой, а здесь это не так.

Спасибо!

РЕДАКТИРОВАТЬ: переключился с will_paginate на 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 голосов
/ 31 октября 2018

Спасибо за обновление. Теперь понятно, где проблема.

Здесь:

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

0 голосов
/ 29 октября 2018

Во-первых, вы, вероятно, действительно не хотите создавать запрос с интерполяцией строк, как вы. Если это приложение доступно в Интернете, плохие парни могут вставить в этот запрос все, что захотят. См. «Небезопасное» предупреждение здесь и как использовать ? в ваших запросах: 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)
...