Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 17.01.2015 17:50:30

Сложные запросы с JOIN

Здравствуйте. Подсобите с составлением запроса.
Каков порядок условий при использовании Join'ов?

Попытался составить нечто похоже на это, но на выхлопе получается объект.

 $messages = Dialog::orderBy('dialogs.id', 'desc')->where('is_deleted', '=', 0)->leftJoin('users', function($join) {
            $join->on('dialogs.user_id', '=', 'users.id');
        })->select('dialogs.id', 'dialogs.message', 'dialogs.date', 'users.username')->take(20)->get();

Объект с кучей свойств, в т.ч. настройками конкретной модели и пр.

object(Illuminate\Database\Eloquent\Collection)#172 (1) { ["items":protected]=> array(1) { [0]=> object(Dialog)#159 (21) { ["timestamps"]=> bool(false) ["fillable":protected]=...

P.S. Выборка элементарная.
2 таблицы: users и dialogs. Требуется выбрать последние 10 сообщений из таблицы dialogs, и имя пользователя из таблицы users. В dialogs есть ключ user_id.

Изменено ElForastero (17.01.2015 17:56:15)

Не в сети

#2 17.01.2015 19:59:32

Re: Сложные запросы с JOIN

Объект с кучей свойств, в т.ч. настройками конкретной модели и пр.

Потому что используете Eloquent. В вашем случае можно использовать отношения One To Many http://laravel.com/docs/4.2/eloquent#relationships

Изменено Wide (17.01.2015 19:59:51)

Не в сети

#3 18.01.2015 12:25:20

Re: Сложные запросы с JOIN

Потому что используете Eloquent. В вашем случае можно использовать отношения One To Many http://laravel.com/docs/4.2/eloquent#relationships

Скорее One To One. Это что-то вроде общего чата.

Не в сети

#4 18.01.2015 13:37:22

Re: Сложные запросы с JOIN

ElForastero пишет:

Скорее One To One.

Нет, судя по вашему запросу.

Изменено Wide (18.01.2015 13:37:37)

Не в сети

#5 18.01.2015 15:56:22

Re: Сложные запросы с JOIN

Wide пишет:

Нет, судя по вашему запросу.

dialogs - это сообщения чата. Имя выбрано не совсем удачно. Одно сообщение принадлежит одному пользователю. Разве не One To One?
Я не пытаюсь выбрать все сообщения одного пользователя. Напротив, пытаюсь узнать `username` оставившего сообщение.
Поправьте, пожалуйста, если не прав.


mysql> describe users;
+-----------------+------------------+------+-----+---------------------+----------------+
| Field           | Type             | Null | Key | Default             | Extra          |
+-----------------+------------------+------+-----+---------------------+----------------+
| id              | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| email           | varchar(255)     | NO   | UNI | NULL                |                |
| username        | varchar(16)      | NO   | UNI | NULL                |                |
| password        | varchar(60)      | NO   |     | NULL                |                |
| joined_at       | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| remember_token  | varchar(100)     | YES  |     | NULL                |                |
| validation_code | varchar(255)     | YES  |     | NULL                |                |
| status          | tinyint(4)       | NO   |     | NULL                |                |
+-----------------+------------------+------+-----+---------------------+----------------+
mysql> describe dialogs;
+------------+------------------+------+-----+---------------------+----------------+
| Field      | Type             | Null | Key | Default             | Extra          |
+------------+------------------+------+-----+---------------------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| user_id    | int(10) unsigned | NO   |     | NULL                |                |
| date       | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| is_deleted | tinyint(1)       | NO   |     | NULL                |                |
| message    | text             | NO   |     | NULL                |                |
+------------+------------------+------+-----+---------------------+----------------+

На выходе нужна вот такая конструкция:

mysql> select dialogs.id, users.username, dialogs.date, dialogs.message from dialogs left join users on dialogs.user_id = users.id and dialogs.is_deleted = 0 order by dialogs.id desc limit 10;
+----+-------------+---------------------+------------------------------------------+
| id | username    | date                | message                                  |
+----+-------------+---------------------+------------------------------------------+
| 68 | ElForastero | 2015-01-17 15:30:35 | Здесь был Юлий!!!!!!                 |
| 67 | ElForastero | 2015-01-17 15:30:20 | Привет, мир!                             |
| 66 | ElForastero | 2015-01-17 15:29:57 | 22rewrwrewaewrawer                       |
| 65 | ElForastero | 2015-01-17 15:29:48 | 22rewrw                                  |
| 64 | ElForastero | 2015-01-17 15:29:37 | 22                                       |
| 63 | ElForastero | 2015-01-17 15:27:14 | 11111                                    |
| 62 | ElForastero | 2015-01-17 15:26:49 | qwqwqwqwww                               |
| 61 | ElForastero | 2015-01-17 15:26:32 | qwqwqwq                                  |
| 60 | ElForastero | 2015-01-17 15:26:05 | qwr2                                     |
| 59 | ElForastero | 2015-01-17 15:25:29 | qwe1                                     |
+----+-------------+---------------------+------------------------------------------+

Не в сети

#6 18.01.2015 17:46:19

Re: Сложные запросы с JOIN

User has many Dialogs
Dialog belongs to User

Eloquent сначала получает одну модель, а затем все её связи:

User::with('dialogs')->where('id', '=', 1)->get();
select * from `users` where `id` = ?
select * from `dialogs` where `dialogs`.`user_id` in (?)

На выходе:

Array
        (
            [id] => 1
            [username] => User
            [dialogs] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [user_id] => 1
                            [message] => 
                        )

                    [1] => Array
                        (
                            [id] => 2
                            [user_id] => 1
                            [message] => 
                        )

Обратная связь:

Dialog::with('user')->get();
select * from `dialogs`
select * from `users` where `users`.`id` in (?)

На выходе:

    [0] => Array
        (
            [id] => 1
            [user_id] => 1
            [message] => 
            [user] => Array
                (
                    [id] => 1
                    [username] => User
                )

        )

    [1] => Array
        (
            [id] => 2
            [user_id] => 1
            [message] => 
            [user] => Array
                (
                    [id] => 1
                    [username] => User
                )

        )

Если на выходе не нужна коллекция, используйте метод toArray()

Не в сети

#7 05.08.2015 14:27:36

Re: Сложные запросы с JOIN

На мой взгляд из той же области только не могу понять как организовать запрос: Имеются таблицы posts и comments соответственно
Post hasMany Comment
Comment belongTo Post
На выходе хочется получить массив постов(а точнее в дальнейшем преобразовать его в json) с количеством комментариев у каждого из них. Сколько не искал, пока найти ответ на данный вопрос никак не могу.

upd. в данный момент реализовано решение в лоб: $result = Post::select('id', 'title')->with('comments')->get(); и в дальнейшем вручную формирую json строку, так как само собой вариант Json::encode($result); добавляет и сами комментарии.

Изменено TuX560 (05.08.2015 14:32:14)

Не в сети

Подвал раздела