Rails will_paginate показывает дубликаты в моделях HABTM

Я использую will_paginate с отношением HABTM между сообщениями в блоге и тегами. Всякий раз, когда я применяю разбиение на страницы, я получаю дублирующиеся сообщения, потому что HABTM в Rails не сохраняет уникальность базы данных, он применяет уникальность при выполнении запроса.

blog_posts.rb

has_and_belongs_to_many :tags, :uniq => true

тег.rb

has_and_belongs_to_many :blog_posts, :uniq => true

Согласно документации для ActiveRecord, :uniq не предотвращает дублирование связей. хранятся, он просто игнорирует их при построении запроса.

Вот проблема: tag = Tag.find(1) tag.blog_posts.count равно 1, но: tag.blog_posts.page(nil).count равно 3, и все 3 являются дубликатами одного и того же сообщения. Правильное поведение должно состоять в том, чтобы показывать только 1, а не дублировать.

Я знаю, что мог бы просто скопировать генерируемые здесь SQL-запросы и исправить их таким образом, но это не кажется хорошим решением. Может ли кто-нибудь помочь мне решить основную проблему? (хотя я обеспокоен тем, что это ошибка в will_paginate)

Редактировать: похоже, это проблема и с Каминари.


person John    schedule 30.07.2012    source источник


Ответы (1)


Я думаю, что уже сталкивался с этой проблемой. Попробуйте добавить это в свой запрос:

.group("id")

Это не ошибка в will_paginate, потому что все, что он делает, это берет данные, которые он вам дает, и разбивает их на страницы в представлении. Решение кроется в данных, которые вы ему предоставляете.

person Ultimation    schedule 31.07.2012
comment
Это работает! Но я не согласен, я думаю, что это ошибка. will_paginate игнорирует спецификации ActiveRecord. Вещи работают без will_paginate, они не работают с ним, потому что он изменяет обычный SQL-запрос ActiveRecord, и вам нужно приложить все усилия, чтобы все заработало. Большое спасибо за решение!!! - person John; 31.07.2012
comment
Да, спасибо Ultimation — согласен, что это можно считать ошибкой или, по крайней мере, улучшением для will_paginate. - person Brett; 30.07.2016