Получить определенные столбцы, используя функцию "With()" в Laravel Eloquent
У меня есть две таблицы: User
и Post
. Один User
может иметь много posts
а один post
принадлежит только одному user
.
В моей модели User
меня есть отношение hasMany
...
public function post(){
return $this->hasmany('post');
}
И в моей post
модели у меня есть belongsTo
отношение...
public function user(){
return $this->belongsTo('user');
}
Теперь я хочу объединить эти две таблицы, используя Eloquent with()
но хочу конкретные столбцы из второй таблицы. Я знаю, что могу использовать Query Builder, но не хочу.
Когда в модели Post
я пишу...
public function getAllPosts() {
return Post::with('user')->get();
}
Он запускает следующие запросы...
select * from 'posts'
select * from 'users' where 'users'.'id' in (<1>, <2>)
Но то, что я хочу, это...
select * from 'posts'
select id,username from 'users' where 'users'.'id' in (<1>, <2>)
Когда я использую...
Post::with('user')->get(array('columns'....));
Возвращает только столбец из первой таблицы. Я хочу, чтобы конкретные столбцы, используя with()
из второй таблицы. Как я могу это сделать?
Ответы
Ответ 1
Ну, я нашел решение. Это можно сделать, передав функцию closure
в with()
в качестве второго индекса массива, например
Post::with(array('user'=>function($query){
$query->select('id','username');
}))->get();
Он будет выбирать только id
и username
из другой таблицы. Я надеюсь, что это поможет другим.
Помните, что первичный ключ (в данном случае идентификатор) должен быть первым параметром в $query-> select() для фактического получения необходимых результатов. *
Ответ 2
В вашей модели Post
public function user()
{
return $this->belongsTo('User')->select(array('id', 'username'));
}
Оригинальный кредит отправляется Laravel Eager Loading - Загрузка только определенных столбцов
Ответ 3
Вы можете сделать это так с Laravel 5.5:
Post::with('user:id,username')->get();
Заботьтесь о поле id
и foreign keys
, как указано в документах:
При использовании этой функции вы всегда должны включать столбец id и любые соответствующие столбцы внешнего ключа в списке столбцов, которые вы хотите получить.
Например, если пользователь принадлежит к команде и имеет team_id
в качестве столбца внешнего ключа, то $post->user->team
будет пустым, если вы не укажете team_id
Post::with('user:id,username,team_id')->get();
Ответ 4
При переходе в другую сторону (hasMany):
User::with(array('post'=>function($query){
$query->select('id','user_id');
}))->get();
Не забудьте включить внешний ключ (при условии, что в этом примере это user_id), чтобы разрешить отношение, иначе вы получите нулевой результат для вашего отношения.
Ответ 5
В Laravel 5.7 вы можете вызывать определенное поле следующим образом
$users = App\Book::with('author:id,name')->get();
Важно добавить поле foreign_key
в выделение.
Ответ 6
В вашей модели Post
:
public function userWithName()
{
return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}
Теперь вы можете использовать $post->userWithName
Ответ 7
Я сталкивался с этой проблемой, но со вторым слоем связанных объектов. Ответ @Awais Qarni имеет место с включением соответствующего внешнего ключа во вложенный оператор выбора. Так же, как идентификатор требуется в первом вложенном операторе выбора для ссылки на связанную модель, внешний ключ необходим для ссылки на вторую степень связанных моделей; в этом примере модель компании.
Post::with(['user' => function ($query) {
$query->select('id','company_id', 'username');
}, 'user.company' => function ($query) {
$query->select('id', 'name');
}])->get();
Кроме того, если вы хотите выбрать конкретные столбцы из модели Post, вам нужно будет включить столбец user_id в оператор выбора, чтобы ссылаться на него.
Post::with(['user' => function ($query) {
$query->select('id', 'username');
}])
->select('title', 'content', 'user_id')
->get();
Ответ 8
Обратите внимание, что если вам нужен только один столбец из таблицы, тогда использование списков - это хорошо. В моем случае я получаю любимые статьи пользователя, но мне нужны только идентификаторы статей:
$favourites = $user->favourites->lists('id');
Возвращает массив идентификаторов, например:
Array
(
[0] => 3
[1] => 7
[2] => 8
)
Ответ 9
Вы также можете указать столбцы на связанной модели во время доступа к ней.
Post::first()->user()->get(['columns....']);
Ответ 10
Теперь вы можете использовать метод pluck
для экземпляра Collection
:
Это вернет только атрибут uuid
Post model
App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
all: [
"1",
"2",
"3",
],
}
Ответ 11
Попробуйте с условиями.
$id = 1;
Post::with(array('user'=>function($query) use ($id){
$query->where('id','=',$id);
$query->select('id','username');
}))->get();
Ответ 12
Когда вы установите отношение в модели, попробуйте это
$postdata = Post::with('user')->get();
$posdata = $postdata->map(function(posts){
return collection([
............
...........
'user' => $posts->user->map(function($user){
'id' => $user->id,
'username' => $user->username
})
])
})
Ответ 13
EmployeeGatePassStatus::with('user:id,name')->get();