Простой SQL для красноречивого запроса (Laravel)

У меня есть две таблицы: пользователи (Пользователи) и группы (Группы).

    Users
    -----------------
    id | username | group
     1 | Bob      | 2

    Groups
    -----------------
    id | name
     1 | firstgroup
     2 | secondgroup

Я хотел бы отобразить: users.ID, users.username, group.name (1, Bob, secondgroup). Такой оператор SQL будет работать:

SELECT Users.id, Users.username, Groups.name
FROM Users
INNER JOIN 
Groups ON Groups.id = Users.group

Однако я изо всех сил пытаюсь написать это в Eloquent, поскольку здесь нет "FROM". На данный момент я собираюсь сделать что-то вроде приведенного ниже, используя JOINS (http://laravel.com/docs/queries#joins)

$users = Users::select('id','username', 'Groups.name')->joins('Groups.id', '=', 'id')->get();

Теперь это не работает - я думаю, что соединения должны быть до выбора, но я просто не могу с этим справиться :(


person Alias    schedule 21.06.2013    source источник


Ответы (2)


Я думаю, вы тут кое-что путаете ...

Вы смешиваете Eloquent с синтаксисом DB::table('foo')->select() нижнего уровня. Если вы хотите использовать Eloquent, я предлагаю вам взглянуть на документы об отношениях в Eloquent.

Вы должны определить свои модели так:

class User extends Eloquent {
    public function group()
    {
        return $this->belongsTo('Group', 'group');
        // second parameter is necessary because you didnt
        // name the column "group_id" but simply "group"
    }
}

class Group extends Eloquent {
    public function users()
    {
        return $this->hasMany('User', 'group');
    }
}

Это настроит все объединения, которые могут вам понадобиться позже. Затем вы можете просто использовать User::with('group')->all();, и запрос будет построен и запущен за вас.

person Nils Werner    schedule 21.06.2013
comment
Вы уверены, что функция group () верна? Кажется, я получаю данные обратно, но если мой идентификатор пользователя равен 1, он также возвращает мне данные для группы с идентификатором одного! - person Alias; 21.06.2013
comment
Согласно вашему вопросу, пользователь 1 находится в группе 1. - person Nils Werner; 21.06.2013
comment
Ах нет, извините, пользователь может быть в любой группе (изменена таблица, чтобы отразить реальный сценарий). Поэтому я хотел бы захватить всех своих пользователей, а затем сказать, в какой группе они находятся. В настоящее время похоже, что мой идентификатор пользователя совпадает с идентификатором группы, а не группа моих пользователей с идентификатором группы. - person Alias; 21.06.2013
comment
в этом случае вы должны использовать all() вместо find(id). Я обновил свой ответ. Что дает вам решение в настоящее время? Всегда назначен группе с тем же идентификатором, что и пользователь? - person Nils Werner; 21.06.2013
comment
Вы можете попробовать удалить специальный ключ 'group' в объявлении belongsTo(), я не уверен, должен ли он там присутствовать. - person Nils Werner; 21.06.2013
comment
paste.laravel.com/xPr Надеюсь, это имеет больше смысла ... Обратите внимание, что я назвал вещи во множественном числе .. , я знаю, что этого делать не следует, но в то время я не понимал! - person Alias; 21.06.2013
comment
$this->hasOne('Groups', 'id'); неверно. Вы всегда ссылаетесь на внешний ключ, а не на локальный. - person Nils Werner; 21.06.2013
comment
Если я изменю ('Группы', 'id') на ('Группы', 'группа'), он скажет Неизвестный столбец 'groups.group' в 'where clause'. Вот почему я думал, что это должен быть идентификатор, поскольку это единственное, на что он может ссылаться! Это сбивает меня с толку, ха-ха. - person Alias; 21.06.2013
comment
Я думаю, вы должны использовать belongsTo вместо hasOne для объявления обратной связи. Кроме того, удалите внешний ключ, установив один из них и установив для другого значение «group». Кроме того ... понятия не имею. Начать сначала ;-) - person Nils Werner; 21.06.2013
comment
Ха-ха, чувак, я не знаю ... $ users = Groups :: with ('users') - ›get (); работает, но не так (показывает группы с пользователями в нем, а не пользователей и их группы). - person Alias; 21.06.2013
comment
Вы не должны использовать group в качестве имени столбца (по нескольким причинам), переименуйте его в group_id. Затем настройте свои красноречивые модели. - person Rob W; 22.06.2013

База данных: построитель запросов (БД) не является красноречивым (ORM):

В построителе запросов к базе данных вы должны указать имена таблиц и поля, как это указано в вашей связанной ссылке документации laravel: «... предоставляет удобный и понятный интерфейс для создания и выполнения запросов к базе данных», как этот запрос ниже:

$users = DB::table('users')
        ->join('contacts', 'users.id', '=', 'contacts.user_id')
        ->join('orders', 'users.id', '=', 'orders.user_id')
        ->select('users.*', 'contacts.phone', 'orders.price')
        ->get();

Eloquent - это сопоставление, связанное с ORM - объектом, это означает, что ваш класс User связан с таблицей users (посмотрите на файлы Migrations), и этот класс расширяет класс модели, поэтому вы можете получить доступ к таким методам, как эти ниже:

class User extends Models
{
    public static function usersWithGroups(){
        return User::select('id', 'name', 'email')->with('groups')->get();
    }
}

Обратите внимание, что этот метод находится в классе User, поэтому вы можете получить к нему статический доступ "User ::", используя Eloquent, у вас будет много скрытых статических методов, которые улучшат ваше кодирование времени, потому что вы наследуют методы de Model, чтобы получить более подробную информацию, посетите Eloquent Docs по адресу: Eloquent Docs < / а>

person Deividson Calixto    schedule 04.10.2019