Как исправить объект запроса, чтобы он правильно отображал данные в Rails 5 - PullRequest
1 голос
/ 27 апреля 2019

Мне нужен свежий взгляд на мой объектный запрос.Идея состоит в том, чтобы показать из базы данных всех пользователей, у которых есть только один клиент (own_to: user), которые не подписаны.

моделей

user
  has_many :customers
  has_many :customers_users

customer
  has_many :customers_users
  belongs_to :user

customers_user
  belongs_to :user
  belongs_to :customer

customer_subscription
  belongs_to :customer

query

Customer.
  joins("LEFT JOIN customer_subscriptions ON customer_subscriptions.customer_id = customers.id").
  where(customer_subscriptions: { id: nil }).
  joins("RIGHT JOIN customers_users ON customers_users.customer_id = customers.id").
  group(:user_id).
  having("count(user_id) = ?", 1).
  count

Но в конце концов у меня есть только user_id без данных, таких как имя, адрес электронной почты, псевдоним и т. д. Я думал, что проблема в count в конце, но без countЯ получил ошибку NoMethodError: undefined method 'having' for main:Object

Можно ли получить эти данные за один запрос?

1 Ответ

1 голос
/ 27 апреля 2019

В вашем случае, я думаю, отрицательное условие в объединении будет работать. Таким образом, запрос будет выглядеть так:

SELECT * FROM users
INNER JOIN customers
ON customers.user_id = users.id
INNER JOIN customers_subscriptions
ON customers_subscriptions.customer_id != customers.user_id
GROUP BY users.id
HAVING COUNT(users.id) = 1

Итак, имея:

Пользователи:

+----+-------+------------+----------------------------+----------------------------+
| id | email | name       | created_at                 | updated_at                 |
+----+-------+------------+----------------------------+----------------------------+
|  1 | NULL  | seb        | 2019-04-27 19:16:09.043251 | 2019-04-27 19:16:09.043251 |
|  2 | NULL  | sab        | 2019-04-27 19:16:09.150315 | 2019-04-27 19:16:09.150315 |
|  3 | NULL  | washington | 2019-04-27 19:58:01.737446 | 2019-04-27 19:58:01.737446 |
+----+-------+------------+----------------------------+----------------------------+

Клиенты:

+----+------------+-------+---------+----------------------------+----------------------------+
| id | name       | email | user_id | created_at                 | updated_at                 |
+----+------------+-------+---------+----------------------------+----------------------------+
|  1 | Sab        | NULL  |       1 | 2019-04-27 19:16:09.254955 | 2019-04-27 20:02:47.636143 |
|  2 | Seb        | NULL  |       2 | 2019-04-27 19:16:09.313268 | 2019-04-27 20:02:55.741603 |
|  3 | Washington | NULL  |       3 | 2019-04-27 19:58:22.711897 | 2019-04-27 19:58:45.213720 |
|  4 | Eminem     | NULL  |       3 | 2019-04-27 19:58:52.820731 | 2019-04-27 20:03:02.465681 |
+----+------------+-------+---------+----------------------------+----------------------------+

Подписки клиентов:

+----+-------------+----------------------------+----------------------------+
| id | customer_id | created_at                 | updated_at                 |
+----+-------------+----------------------------+----------------------------+
|  1 |           1 | 2019-04-27 19:16:10.041788 | 2019-04-27 19:16:10.041788 |
|  2 |           3 | 2019-04-27 20:04:16.464446 | 2019-04-27 20:04:16.464446 |
+----+-------------+----------------------------+----------------------------+

Результат должен быть:

+----+-------+------+----------------------------+----------------------------+----+------+-------+---------+----------------------------+----------------------------+----+-------------+----------------------------+----------------------------+
| id | email | name | created_at                 | updated_at                 | id | name | email | user_id | created_at                 | updated_at                 | id | customer_id | created_at                 | updated_at                 |
+----+-------+------+----------------------------+----------------------------+----+------+-------+---------+----------------------------+----------------------------+----+-------------+----------------------------+----------------------------+
|  1 | NULL  | seb  | 2019-04-27 19:16:09.043251 | 2019-04-27 19:16:09.043251 |  1 | Sab  | NULL  |       1 | 2019-04-27 19:16:09.254955 | 2019-04-27 20:02:47.636143 |  2 |           3 | 2019-04-27 20:04:16.464446 | 2019-04-27 20:04:16.464446 |
+----+-------+------+----------------------------+----------------------------+----+------+-------+---------+----------------------------+----------------------------+----+-------------+----------------------------+----------------------------+

Таким образом, код AR для этого может быть:

User.
  joins(:customers).
  joins('INNER JOIN customers_subscriptions ON customers_subscriptions.customer_id != customers.user_id').
  group(:id).
  having('COUNT(users.id) = 1')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...