Рельсы активной записи запроса с сортировкой и лимитом
Я пытаюсь собрать достаточно сложный запрос Active Record, и я довольно новичок в Rails.
Отношения
Вот соответствующие модельные отношения для запроса:
- команды могут иметь многопользователей . У пользователей есть столбецteam_id , чтобы отслеживать, в какой команде они находятся. Команды имеют одного администратора, который является пользователем. Это находится в столбцеadmin_id команды.
- пользователи имеют электронную почту адрес (напр. foo@example.com).
Схема
Вот соответствующие части schema.rb
:
create_table "teams", force: :cascade do |t|
t.integer "admin_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.integer "team_id"
end
add_foreign_key "teams", "users", column: "admin_id"
add_foreign_key "users", "teams"
Запрос
Дано доменное имя (напр. example.com), я хотел бы найти команды, у которых есть администраторы с адресом электронной почты с этим доменным именем. Если есть несколько матчей, я хотел бы только команду с наибольшим количеством пользователей. Вот что у меня есть до сих пор:
team = Team.joins('INNER JOIN users ON admin_id = users.id')
.where('email LIKE ?', "%example.com")
.where(domain_sign_up: true)
Задача
Проблема с этим запросом заключается в том, что он возвращает все совпадения в виде массив. Я хотел бы упорядочить его по team.users.count
, а затем вернуть только первую (с большинством пользователей) команду в качестве объекта, а не массива. Может быть, это кандидат на LEFT OUTER JOIN
?
Спасибо!
2 ответа:
Попробуйте что-нибудь вроде этого
team = Team.joins('INNER JOIN users ON admin_id = users.id') .where('email LIKE ?', "%example.com") .where(domain_sign_up: true) .group('teams.id') .select('teams.*, COUNT(users.id) AS team_users_count') .order('COUNT(users.id) DESC') .first
Я изменил
limit(1)
наfirst
. Кажется, что это не имеет большого смыслаlimit
, если параметр равен 1, поэтому у вас естьTeam
, а не отношение одной команды.
Ответ, опубликованный Ursus, был весьма полезен, однако я закончил тем, что добавил новый столбец в команду под названием domain Для упрощения вещей, а затем использовал
.left_join
для заказа пользователями. Вот мой последний вопрос:team = Team.left_joins(:users) .where(domain: 'example.com', domain_sign_up: true) .group('teams.id') .order('COUNT(users.id) DESC') .first