У меня есть одна вещь, которую нужно добавить к отличному ответу elektronaut: он не будет работать на PostgreSQL.
В моем реальном примере вызов Item.all включает другие таблицы;таким образом, выборка выглядит следующим образом:
SELECT items.id AS t0_f0, items.name as t0_f1 ..., table2.field1 as t1_f0 .. etc
GROUP BY в PostgreSQL требует, чтобы все поля , используемые для выбора, были включены туда.Поэтому мне пришлось включить все поля, использованные в предыдущем выборе, в предложение GROUP BY.
И все же это не сработало;Я не уверен почему.
Я закончил тем, что сделал более простую и уродливую вещь.Требуется два запроса дб.Один из них используется для возврата идентификаторов, которые используются в качестве условия.
class Item < ActiveRecord::Base
# returns the ids of the items tagged with all tags
# usage: Item.tagged_all(1,2,3)
named_scope :tagged_all, lambda { |*args|
{ :select => "items.id",
:joins => :tags,
:group => "items.id",
:having => ['COUNT(items.id) >= ?', args.length],
:conditions => ["tags.id IN (?)", args]
}
}
Тогда я могу сделать это:
Item.all(
:conditions => [
'items.id IN (?) AND ... (other conditions) ...',
Items.tagged_all(*tag_ids).collect(&:id),
... (other values for conditions) ...
],
:includes => [:model2, :model3] #tags isn't needed here any more
)
Хаки, но это работает, и хакерство локализовано.