У меня есть две таблицы User
и Post
One 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()
из второй таблицы. Как я могу это сделать?
Ну, я нашел решение. Это можно сделать путем передачи функции closure
в with()
в качестве второго индекса массива типа
Post::with(array('user'=>function($query){
$query->select('id','username');
}))->get();
Он выберет только id
и username
из другой таблицы. Надеюсь, это поможет другим.
Помните, что первичный ключ (id в этом случае) необходим в $query- > select() для фактического получения необходимых результатов.
В вашей модели Post
public function user()
{
return $this->belongsTo('User')->select(array('id', 'username'));
}
Оригинальный кредит отправляется Laravel Eager Loading - Загрузка только определенных столбцов
При движении другим способом (hasMany):
User::with(array('post'=>function($query){
$query->select('id','user_id');
}))->get();
Не забудьте включить внешний ключ (при условии, что он является user_id в этом примере), чтобы разрешить взаимосвязь, иначе вы получите нулевые результаты для своего отношения.
В вашей модели Post
:
public function userWithName()
{
return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}
Теперь вы можете использовать $post->userWithName
Вы можете сделать это в Laravel 5.5:
Post::with('user:id,username')->get();
Уход за полем id
, как указано в docs:
При использовании этой функции вы всегда должны включать столбец id в список столбцов, которые вы хотите получить.
Обратите внимание, что если вам нужен только один столбец из таблицы, то использование "списков" довольно хорошо. В моем случае я извлекаю любимые статьи пользователя, но мне нужен только идентификатор статьи:
$favourites = $user->favourites->lists('id');
Возвращает массив идентификаторов, например:
Массив ( [0] = > 3 [1] = > 7 [2] = > 8 )
toArray()
!!! $user->favourites->lists('id')->toArray();
Теперь вы можете использовать метод pluck
для экземпляра Collection
:
Это вернет только атрибут uuid
Post model
App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
all: [
"1",
"2",
"3",
],
}
$query->select('id','username');
Trying to get property of non-object
hasmany
иbelongsto
к вашей модели ??