Если вам нужны только эти конкретные столбцы и больше ничего, тогда это будет работать
User.joins(:post)
.where(id: [1,2,3])
.select("users.id, users.name, users.timestamp,
posts.id as post_id, posts.user_id as post_user_id,
posts.title as post_title")
Это вернет ActiveRecord::Relation
из User
объектов с виртуальными атрибутами для post_id
, post_user_id
(Не уверен, зачем вам это нужно, так как вы уже выбрали users.id
) и post_title
.
Полученный запрос будет
SELECT users.id,
users.name,
users.timestamp,
posts.id as post_id,
posts.user_id as post_user_id,
posts.title as post_title
FROM users
INNER JOIN posts on posts.user_id = users.id
where users.id IN ( 1, 2, 3);
Обратите внимание, у вас может быть несколько User
объекты, по одному на каждый Post
, так же, как это делает запрос SQL.
Вы можете выполнить свой точный запрос, используя строковую версию joins
, например,
User.joins("INNER JOIN (SELECT id, user_id, title, from, to FROM posts) b on b.user_id = users.id")
.where(id: [1,2,3])
.select("users.id, users.name, users.timestamp,
b.id as post_id, b.user_id as post_user_id,
b.title as post_title")
Дополнительно, чтобы избежать некоторыхиз накладных расходов вы можете использовать arel
вместо, например,
users_table = User.arel_table
posts_table = Post.arel_table
query = users_table.project(Arel.star)
.join(posts_table)
.on(posts_table[:user_id].eq(users_table[:id]))
.where(users_table[:id].in([1,2,3]))
ActiveRecord::Base.connection.exec_query(query.to_sql)
Это вернет ActiveRecord::Result
с 2 полезными методами columns
(выбранные столбцы) и rows
.Вы можете преобразовать это в Hash
(#to_hash
), но учтите, что любые столбцы с повторяющимися именами (например, id
) будут перезаписывать друг друга.
Вы можете исправить это, указав нужные столбцы в части project
.Например, ваш текущий запрос будет выглядеть следующим образом:
query = users_table.project(
users_table[:id],
users_table[:name],
users_table[:timestamp],
posts_table[:id].as('post_id'),
posts_table[:user_id].as('post_user_id'),
posts_table[:title].as('post_title')
).join(posts_table)
.on(posts_table[:user_id].eq(users_table[:id]))
.where(users_table[:id].in([1,2,3]))
ActiveRecord::Base.connection.exec_query(query.to_sql).to_hash
Поскольку ни одно из имен теперь не сталкивается, его можно структурировать в симпатичный Hash
, где ключи - это имена столбцов и значения или значение строки для этой записи..