Поскольку предложение where ограничивает загруженные записи, вам может понадобиться использовать подзапрос:
User.includes(:roles).where(
id: User.joins(:roles).where(roles: { name: params[:roles] })
)
Если вы посмотрите на сгенерированный SQL, то увидите, что предложение where здесь применимо только к подзапросу - таким образом, загружаются все связанные роли, а не только те, которые соответствуют WHERE "roles"."name" = $1
.
User Load (3.0ms) SELECT "users".* FROM "users" WHERE "users"."id" IN (SELECT "users"."id" FROM "users" INNER JOIN "user_roles" ON "user_roles"."user_id" = "users"."id" INNER JOIN "roles" ON "roles"."id" = "user_roles"."role_id" WHERE "roles"."name" IN ($1, $2, $3)) LIMIT $4 [["name", "admin"], ["name", "foo"], ["name", "bar"], ["LIMIT", 11]]
UserRole Load (0.6ms) SELECT "user_roles".* FROM "user_roles" WHERE "user_roles"."user_id" = $1 [["user_id", 1]]
Role Load (0.5ms) SELECT "roles".* FROM "roles" WHERE "roles"."id" = $1 [["id", 1]]
Также, если вы хотите использовать загруженные записи, вам нужно использовать map
, а не pluck
, так как сборщик данных создает отдельный запрос на выборку.
def roles
object.roles.map(&:name)
end