Я не знаю, решит ли это вашу проблему, но для таких сложных запросов я почти всегда просто использую Squeel .
Затем сделайте что-то вроде этого:
@posts = Post.joins(:tags)
.where{tags.name.like_any names_array}
.group("post_id")
.having("count(post_id) = #{names_array.size}")
Надеемся, что SQL выглядит примерно так
SELECT "posts".* FROM "posts"
INNER JOIN "tags" ON "tags"."post_id" = "posts"."id"
WHERE (("tags"."name" LIKE "TagA" OR "tags"."name" LIKE "TagB"))
GROUP BY post_id
HAVING count(post_id) = 2
Если я помню, squeel довольно хорошо использует ILIKE вместо LIKE в зависимости от используемой базы данных.(по крайней мере, лучше, чем AR)
Также вы можете сделать это, используя AR без squeel , но мне ДЕЙСТВИТЕЛЬНО нравятся некоторые идеи и помощники, которые идут с squeel как _all
Что касается объяснения ...
Предположим, я искал Теги A и B.
Что делает, так это находит все Сообщения с этими тегами.
Таким образом, у вас будет что-то вроде:
- PostA TagA
- PostA TagB
- PostB TagA
- PostB TagB
- PostC TagA
Затем он объединит все эти различные результаты Post по объединенным тегам, используя post_id.
- PostA TagA TagB
- PostBTagA TagB
- PostC TagA
Затем он проверит количество тегов в строке SQL, проверив, сколько присутствует forgien_ids.Поскольку A и B имеют 2 тега, вы знаете, что они совпадают со всеми введенными вами.