Использование will_paginate с несколькими моделями (Rails)

Почти уверен, что мне не хватает чего-то действительно простого:

Я пытаюсь отобразить серию страниц, содержащих экземпляры двух разных моделей — профилей и групп. Мне нужно, чтобы они упорядочивались по атрибуту имени. Я мог бы выбрать все экземпляры для каждой модели, а затем отсортировать их и разбить на страницы, но это кажется неаккуратным и неэффективным.

Я использую mislav-will_paginate, и мне было интересно, есть ли лучший способ добиться этого? Что-то типа:

[Profile, Group].paginate(...)

было бы идеально!


person Codebeef    schedule 07.07.2009    source источник


Ответы (4)


Хороший вопрос, пару раз сталкивался с одной и той же проблемой. Каждый раз я заканчивал это тем, что писал свой собственный sql-запрос на основе sql-объединений (он отлично работает с sqlite и mysql). Затем вы можете использовать разбиение на страницы, передав результаты (http://www.pathf.com/blogs/2008/06/how-to-use-will_paginate-with-non-activerecord-collectionarray/). Не забудьте выполнить запрос для подсчета всех строк.

Некоторые строки кода (не тестировались)

my_query = "(select posts.title from posts) UNIONS (select profiles.name from profiles)"
total_entries = ActiveRecord::Base.connection.execute("select count(*) as count from (#{my_query})").first['count'].to_i

results = ActiveRecord::Base.connection.select_rows("select * from (#{my_query}) limit #{limit} offset #{offset}")

Это перебор? Возможно, но у вас есть минимальное количество запросов, и результаты непротиворечивы.

Надеюсь, поможет.

Примечание. Если вы получаете значение смещения из параметра http, вы должны использовать sanitize_sql_for_conditions (т. е. внедрение sql....)

person Community    schedule 02.09.2009

Вы можете приблизиться, выполнив что-то вроде:

@profiles, @groups = [Profile, Group].map do |clazz|
  clazz.paginate(:page => params[clazz.to_s.downcase + "_page"], :order => 'name')
end

Затем это будет разбито на страницы с использованием параметров страницы profile_page и group_page. Вы можете получить вызов will_paginate в представлении, чтобы использовать правильную страницу, используя:

<%= will_paginate @profiles, :page_param => 'profile_page' %>
....
<%= will_paginate @groups, :page_param => 'group_page' %>

Тем не менее, я не уверен, что есть огромная польза от индивидуальной настройки @groups и @profiles.

person Shadwell    schedule 07.07.2009

в моем последнем проекте я столкнулся с проблемой, мне пришлось разбить несколько моделей на страницы с одной разбивкой на страницы в моей функции поиска. он должен работать таким образом, чтобы первая модель отображалась первой, когда результаты первой модели вторая модель должна продолжать результаты, а третья и так далее как одна единственная поисковая лента, точно так же, как каналы facebook. это функция, которую я создал для этой функции

def multi_paginate(models, page, per_page)

  WillPaginate::Collection.create(page, per_page) do |pager|

    # set total entries
    pager.total_entries = 0
    counts = [0]
    offsets = []
    for model in models
          pager.total_entries += model.count
          counts << model.count
          offset = pager.offset-(offsets[-1] || 0)
          offset = offset>model.count ? model.count : offset 
          offsets << (offset<0 ? 0 : offset)
    end

    result = []
    for i in 0...models.count
          result += models[i].limit(pager.per_page-result.length).offset(offsets[i]).to_a
    end

    pager.replace(result)
  end

end

попробуйте и дайте мне знать, если у вас возникнут какие-либо проблемы с этим, я также отправил его как проблему в репозиторий will_paginate, если все подтвердят, что он работает правильно, я разветвлю и зафиксирую его в библиотеке. https://github.com/mislav/will_paginate/issues/351

person Emad Elsaid    schedule 16.01.2014

Вы пытались отобразить два разных набора результатов с их собственными пагинаторами и обновить их через AJAX? Это не совсем то, что вы хотите, но результат похож.

person pantulis    schedule 07.07.2009
comment
К сожалению, это не поможет - мне нужно иметь два набора экземпляров вместе. - person Codebeef; 07.07.2009