Всем доброго времени суток!
Прошу помочь, потому что голову уже сломал, пытаясь разобраться почему в выборке оказываются "лишние" данные. Почему лишние ? Вот смотрите.
Есть 2 таблички (MariaDB):
CREATE TABLE `email` (
`email_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`subject` varchar(512) NOT NULL,
`body` longtext NOT NULL,
`status` tinyint(1) unsigned DEFAULT '0',
`created_by` int(10) unsigned NOT NULL,
`created_at` int(10) unsigned NOT NULL,
`updated_at` int(10) unsigned DEFAULT '0',
PRIMARY KEY (`email_id`),
KEY `email_status_IDX` (`status`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='Таблица для хранения email для отправки';
и
CREATE TABLE `email_recipient` (
`email_id` int(10) unsigned NOT NULL,
`email_to` varchar(512) NOT NULL,
`status` tinyint(3) unsigned DEFAULT '0',
KEY `email_recipient_email_id_IDX` (`email_id`,`email_to`(255)) USING BTREE,
CONSTRAINT `email_recipient_fk` FOREIGN KEY (`email_id`) REFERENCES `email` (`email_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Таблица с получателями';
Первая хранит в себе общую информацию об отправляемом письме, вторая хранит получателей (связь по `email_id`).
Тестовые данные такие:
MariaDB [service]> select * From email where email_id = 3;
+----------+----------+----------+--------+------------+------------+------------+
| email_id | subject | body | status | created_by | created_at | updated_at |
+----------+----------+----------+--------+------------+------------+------------+
| 3 | тест | тест | 0 | 2 | 1568143024 | 0 |
+----------+----------+----------+--------+------------+------------+------------+
и соответственно
+----------+---------------+--------+
| email_id | email_to | status |
+----------+---------------+--------+
| 3 | test2@test.ru | 0 |
| 3 | test@test.ru | 1 |
+----------+---------------+--------+
Версия Yii2: 2.0.11.2 (знаю, что нужно обновиться, но пока не могу).
Полный вывод моделей для них приводить не буду, т.к. считаю пока это не требуется, приведу лишь только relation из модели Email:
/**
* @return \yii\db\ActiveQuery
*/
public function getEmailRecipients()
{
return $this->hasMany(EmailRecipient::className(), ['email_id' => 'email_id']);
}
Далее есть консольное приложение, которое и занимается отправкой. Естественно, отправлять нужно только на те адреса, статус у которых 0 (1 - отправка уже была).
Собственно, получаю я данные следующим образом:
$emails = Email::find()
->joinWith('emailRecipients')
->where(['email.status' => Email::EMAIL_STATUS_NEW])
->andWhere(['email_recipient.status' => EmailRecipient::EMAIL_RECIPIENT_STATUS_NEW])
->asArray()
->all();
Я был на 100500% уверен, что получу только письма готовые к отправке (`email`.`status` = 0) и список получателей, которым ещё не отправилось письмо по тем или иным причинам (`email_recipient`.`status` = 0). Но или я где-то сильно ошибся или что-то пошло не так - возвращается мне массив с полным количеством получателей:
array(1) {
[0]=>
array(8) {
["email_id"]=>
string(1) "3"
["subject"]=>
string(8) "тест"
["body"]=>
string(8) "тест"
["status"]=>
string(1) "0"
["created_by"]=>
string(1) "2"
["created_at"]=>
string(10) "1568143024"
["updated_at"]=>
string(1) "0"
["emailRecipients"]=>
array(2) {
[0]=>
array(3) {
["email_id"]=>
string(1) "3"
["email_to"]=>
string(12) "test@test.ru"
["status"]=>
string(1) "1"
}
[1]=>
array(3) {
["email_id"]=>
string(1) "3"
["email_to"]=>
string(13) "test2@test.ru"
["status"]=>
string(1) "0"
}
}
}
}
Решил подебажить и получить запрос, которым достаются данные:
SELECT *
FROM `email`
LEFT JOIN `email_recipient` ON `email`.`email_id` = `email_recipient`.`email_id`
WHERE (`email`.`status`=0)
AND (`email_recipient`.`status`=0);
Всё ровно:
+----------+----------+----------+--------+------------+------------+------------+----------+---------------+--------+
| email_id | subject | body | status | created_by | created_at | updated_at | email_id | email_to | status |
+----------+----------+----------+--------+------------+------------+------------+----------+---------------+--------+
| 3 | тест | тест | 0 | 2 | 1568143024 | 0 | 3 | test2@test.ru | 0 |
+----------+----------+----------+--------+------------+------------+------------+----------+---------------+--------+
1 row in set (0.00 sec)
Ничего специфического не писал. Модели создавались с помощью gii.
Подскажите, пожалуйста, что я упустил или чего-то недопонял в работе связей в Yii2 ?
Заранее всем спасибо!