Есть два подхода, которые я могу придумать (и в зависимости от вашей СУБД, то, что происходит под прикрытием, может быть почти одинаковым):
- создать представление для всех соответствующих полей всех различные полиморфы c
bar
типы - присоединяются к динамической таблице c, которая создается на лету
В обоих случаях базовая логика c является * Команда 1010 *, которая будет выглядеть примерно так:
SELECT foo_id, description FROM bars1
UNION
SELECT foo_id, description FROM bars2
UNION
SELECT foo_id, description FROM bars3
В случае представления это UNION
будет составлять содержимое самого представления.
В случае для таблицы Dynami c она будет выглядеть примерно так:
SELECT foos.*, bars.*
FROM foos
LEFT JOIN (
SELECT foo_id, description FROM bars1
UNION
SELECT foo_id, description FROM bars2
UNION
SELECT foo_id, description FROM bars3
) AS bars ON bars.foo_id = foos.id
WHERE bars.description LIKE 'whatever%'
С точки зрения, использование Arel в основном такое же, как обычно, только вы должны сделать JOIN
явным:
Foo.joins("LEFT JOIN bars ON bars.foo_id = foos.id").where("bars.description LIKE ?", description)
Имея динамический c стол, я уверен, что есть способ express в чистом Ареле, но лично я бы просто go с SQL вместо:
joins_sql = <~SQL.strip_heredoc
LEFT JOIN (
SELECT foo_id, description FROM bars1
UNION
SELECT foo_id, description FROM bars2
UNION
SELECT foo_id, description FROM bars3
) AS bars ON bars.foo_id = foos.id
SQL
Foo.select("foos.*, bars.*").joins(joins_sql).where("bars.description LIKE ?", description)
Надеюсь, это поможет.