Rails:使用带复杂关联的will_paginate查找

时间:2010-05-19 18:54:53

标签: ruby-on-rails activerecord will-paginate

我在进行复杂查找时遇到了will_paginate的问题。

:photo  has_many   :tags,   :through => :tagships
:item   has_many   :photos
:photo  belongs_to :item


@photos = @item.photos.paginate :page => params[:page],
                                :per_page => 200,
                                :conditions => [ 'tags.id IN (?)', tag_ids],
                                :order => 'created_at DESC',
                                :joins => :tags,
                                :group => "photos.id HAVING COUNT(DISTINCT tags.id) = #{tag_count}"

我想获取tag_ids数组中包含所有标签的所有照片。 MySQL的IN通常会进行“或”搜索,但我需要“和”。我发现如何修改IN以模仿“和”行为here并且它在使用model.find()时工作正常,只要获取的记录数低于my:per_page计数,它也可以工作。但如果必须进行分页,则生成的SQL类似于:

SELECT count(*) AS count_all, photos.id HAVING COUNT(DISTINCT tags.id) = 1 AS photos_id_having_count_distinct_tags_id_1 FROM `photos`(...)

哪个不起作用。其他人已经看到了这个错误,并且能够将他们的count()移出查询,但我不认为这是可能的。

有没有更好的方法来执行可能与will_paginate一起使用的搜索?如果它是唯一的方法,我想我应该看看另一个分页插件?

谢谢!

2 个答案:

答案 0 :(得分:4)

仅供参考,我终于找到了解决这个问题的方法:

@photos = WillPaginate::Collection.create(current_page, per_page) do |pager|
    result = @item.photos.find :all, :conditions => [ 'tags.id IN (?)', tag_ids] ,:order => 'created_at DESC', :joins => :tags, :group => "photos.id HAVING COUNT(DISTINCT tags.id) = #{@tags.count}", :limit => pager.per_page, :offset => pager.offset
    pager.replace(result)

    unless pager.total_entries
      pager.total_entries = @item.photos.find(:all, :conditions => [ 'tags.id IN (?)', tag_ids] ,:order => 'created_at DESC', :joins => :tags, :group => "photos.id HAVING COUNT(DISTINCT tags.id) = #{@tags.count}").count
    end
  end

您必须使用页码作为偏移量手动构建分页集,并使用标记进行连接查询。有点笨重。

答案 1 :(得分:1)

我对此的第一次尝试(抱歉没有时间立即测试...如果我这样做会更新)将类似于以下内容(添加:选择并更改:组):

@photos = @item.photos.paginate :page => params[:page],
                                :per_page => 200,
                                :select => "photos.*, COUNT(DISTINCT tags.id) AS tag_count",
                                :conditions => [ 'tags.id IN (?)', tag_ids ],
                                :order => 'created_at DESC',
                                :joins => :tags,
                                :group => "photos.id HAVING tag_count = #{tag_count}"