Laravel Eloquent의 "With ()"함수를 사용하여 특정 열 가져 오기


198

나는 두 개의 테이블을 가지고 UserPost. 하나 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모델 I 쓰기 ...

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()두 번째 테이블에서 특정 열을 사용하고 싶습니다 . 어떻게해야합니까?

답변:


348

글쎄, 나는 해결책을 찾았다. 그것은 배열의 두 번째 인덱스로 closure함수를 전달하여 수행 할 수 있습니다with()

Post::with(array('user'=>function($query){
    $query->select('id','username');
}))->get();

그것은 단지 선택합니다 idusername다른 테이블에서. 이것이 다른 사람들을 도울 수 있기를 바랍니다.


실제로 필요한 결과를 검색 하려면 기본 쿼리 (이 경우 ID)가 $ query-> select () 의 첫 번째 매개 변수 여야합니다 . *


2
이상하다, 나는 이것을 작동시킬 수 없었다. 나는에 추가 자마자 $query->select('id','username');, 내가 얻고 있었다Trying to get property of non-object
user1669496

5
기묘한! 여전히 사용자의 모든 필드를 반환합니다. @AwaisQarni
저스틴

2
이것을 공유해 주셔서 감사합니다. 이 가능성을 어디서 발견 했습니까? 나는 Laravel 문서에서 이것을 찾지 못했습니다.
Symen Timmermans

82
이것을 보는 사람들에게는 실제로 필요한 결과를 검색하기 위해 기본 키 ( id이 경우)가 필요 하다는 것을 기억하십시오 $query->select(). 내 코드에서 이것을 생략하고 왜 결과를 찾지 못하는지를 알 수 없었습니다. 바보 나! 이것이 동일한 문제를 가진 다른 사람들을 돕기를 바랍니다
Azirius

4
좋아, 외래 키를 추가해야합니다. 여기서 post_id 그렇지 않으면 결과가 비어 있습니다. 외래 키 언급이 중요합니다. 감사합니다 :)
Hashaam Ahmed 11:28

105

라 라벨 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();

13
관계를 해결하기 위해 외래 키 (여기서는 post_id라고 가정)를 포함시키는 것을 잊지 마십시오. 그렇지 않으면 관계에 대해 빈 결과가 나타납니다.
Hashaam Ahmed

2
이것은 실제로 선택된 답변이어야합니다. 매력처럼 작동 :)
Graham

@Adam, 자식 테이블의 열을 제한합니다. 자식 테이블과 함께 부모 테이블의 열을 어떻게 제한 할 수 있습니까?
나트륨

@GauravGenius 당신이 get()방법으로 부모의 블로그에서 제한하고 싶은 모든 것Post::with('user:id,username')->get(['age', 'color']);
Adam

82

당신의에서 Post모델

public function user()
{
    return $this->belongsTo('User')->select(array('id', 'username'));
}

원래 크레딧은 Laravel Eager 로딩으로 이동-특정 열만로드


14
그러나이 관계는 하드 코딩 된 것처럼 만들 것입니다. 모든 조건에서 항상이 두 필드를 반환합니다. 다른 상황에서는 더 많은 필드가 필요할 수 있습니다.
Awais Qarni

그런 다음 조회 빌더를 사용해야합니다.
user1669496

5
이것이 정답입니다. 이것이 올바른 방법입니다.
BugHunterUK

1
Laravel 5.3 버전에서이를 수행 할 수있는 방법이 있습니까? 나는 그들이 그것을 다시 생각합니다 ... 다시 .... 그리고 지금이 접근법으로 시도하면 null을 반환합니다
Andre F.

오래되었지만 $fields매개 변수를 추가 할 수 있습니다 .
JordyvD

69

다른 방향으로 갈 때 (hasMany) :

User::with(array('post'=>function($query){
    $query->select('id','user_id');
}))->get();

관계를 해결하기 위해 외래 키 (이 예제에서는 user_id라고 가정)를 포함해야합니다. 그렇지 않으면 관계에 대한 결과가 0이됩니다.


6
예, 정확히 "외래 키를 포함하는 것을 잊지 마십시오 (이 예에서는 user_id라고 가정)"
aqingsao

선택 필드에 관계를 정의하는 열을 포함해야합니다.이 경우 user_id
alimfazeli

좋은 캐치 형제.
Shahrukh Anwar

굉장 형제, 외래 키 사용이 정말 중요합니다. 운이 좋으면 당신의 ans를 보았습니다. 그렇지 않으면 몇 시간 동안 내 머리를 긁었을 것입니다. 고마워요!
Hashaam Ahmed

35

Laravel 5.7에서는 다음과 같은 특정 필드를 호출 할 수 있습니다

$users = App\Book::with('author:id,name')->get();

foreign_key선택 에 필드 를 추가하는 것이 중요합니다 .


12
외래 키 필드를 추가하는 것을 잊지 마십시오
hendra1

2
@ hendra1의 의견을 잊지 마십시오. 기본 키와 함께 모든 외래 키 필드가 필요합니다. 그렇지 않으면 빈 컬렉션이 나타납니다. 친구가 내 시간을 구했다 감사합니다
Rajesh Vishnani

14

당신의에서 Post모델 :

public function userWithName()
{
    return $this->belongsTo('User')->select(array('id', 'first_name', 'last_name'));
}

이제 사용할 수 있습니다 $post->userWithName


2
정말? 나에게 이것은 아무것도 반환하지 않습니다.
Sjwdavies

12

당신은 사용하여 특정 열을 얻고 싶은 경우에 with()원래 그의 대답에 @ 아담 응답하는 다음과 같이 다음 코드를 사용할 수 있습니다 laravel의 웅변에 여기에 이 같은 질문의 응답 :

Post::with('user:id,username')->get();

그래서 나는 그것을 내 코드에서 사용 했지만 오류가 발생했다 1052: Column 'id' in field list is ambiguous. 그래서 너희들도 같은 문제에 직면한다면

그런 다음 해결 하려면 with()아래 코드와 같이 메소드 의 id 열 앞에 테이블 이름을 지정해야합니다 .

Post::with('user:user.id,username')->get();

이것은 나를 위해 null을 반환하지만 이것이 가능하다는 것을 몰랐습니다! 좋아, 나는 prematurley를 게시했지만 결과를 찾았습니다. 이 방법을 사용하려면 (더 깔끔해 보이는) 관계 링크 (예 : with 데이터를 가져올 때 ID 열)를 포함해야합니다. 이 지정자가 없으면 널 리턴이 발생합니다.
Adsy2010

예 @ Adsy2010, 관련 관계 데이터를 얻으려면 id 열이나 기본 키 또는 해당 관계를 담당하는 ID를 가져와야합니다.
Haritsinh Gohil

10

나는이 문제를 겪었지만 관련 객체의 두 번째 레이어를 사용했습니다. @Awais Qarni의 대답은 중첩 된 select 문에 적절한 외래 키가 포함되어 있음을 나타냅니다. 관련된 모델을 참조하기 위해 첫 번째 중첩 된 select 문에 id가 필요한 것처럼 외래 키는 두 번째 정도의 관련 모델을 참조해야합니다. 이 예에서는 회사 모델입니다.

Post::with(['user' => function ($query) {
        $query->select('id','company_id', 'username');
    }, 'user.company' => function ($query) {
        $query->select('id', 'name');
    }])->get();

또한 Post 모델에서 특정 열을 선택하려면이를 참조하기 위해 select 문에 user_id 열을 포함시켜야합니다.

Post::with(['user' => function ($query) {
        $query->select('id', 'username');
    }])
    ->select('title', 'content', 'user_id')
    ->get();

4

테이블에서 하나의 열만 필요하면 'lists'를 사용하는 것이 좋습니다. 제 경우에는 사용자가 좋아하는 기사를 검색하고 있지만 기사 ID 만 원합니다.

$favourites = $user->favourites->lists('id');

id 배열을 반환합니다. 예 :

Array
(
    [0] => 3
    [1] => 7
    [2] => 8
)

컬렉션을 반환합니다!
Giovanni Far

배열을 원하면 toArray()!!! 를 호출하십시오. $user->favourites->lists('id')->toArray();
Giovanni Far

list () 메소드가 결과 배열을 변경하기 때문에 쿼리는 여전히 다른 열을 가져옵니다. 따라서 해당 테이블에서 'id'만 필요하면 쿼리에서 지정하려고 할 수 있습니다. 쿼리를 수행 할 때는 항상 성능을 염두에 두는 것이 좋습니다. 코딩을 즐기십시오!
Ervin Llojku

모든 필드를 선택 $user->favourites하면 -1 이 반환 Collection됩니다. 올바른 사용법은 다음과 같습니다 $user->favourites()->lists('id')..
Wallace Maxters

나중에 PHP 필터링을 사용하기 위해 모든 것을 선택하는 것은 나쁜 생각입니다. Query에서 필요한 필드 만 사용하는 것이 가장 좋습니다. Query\Builder::lists방법과 Collection::lists방법 의 차이점을 아는 것이 중요합니다 .
Wallace Maxters

1

관련 모델에 액세스 할 때 관련 모델에 열을 지정할 수도 있습니다.

Post::first()->user()->get(['columns....']);


0

이제 인스턴스 에서 pluck메소드를 사용할 수 있습니다 Collection.

이것은의 uuid속성 만 반환 합니다Post model

App\Models\User::find(2)->posts->pluck('uuid')
=> Illuminate\Support\Collection {#983
     all: [
       "1",
       "2",
       "3",
     ],
   }

0

조건으로 시도하십시오.

$id = 1;
Post::with(array('user'=>function($query) use ($id){
    $query->where('id','=',$id);
    $query->select('id','username');
}))->get();

-3
EmployeeGatePassStatus::with('user:id,name')->get();

2
이것은 이 답변 과 같은 구문 입니다 (모델과 열의 이름 만 다름)
barbsan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.