2015-01-17 3 views
0

2 테이블 : usersarticles이 있습니다. users 테이블에 is_suspended이라는 열이 있으며 yes 또는 no을 허용하고 articles 테이블에는 0 또는 1을 허용하는 is_published이라는 열이 있습니다. 데이터베이스에서 아티클 데이터를 가져 오려면 articles.is_published1이어야하며 users.is_suspendedno과 같아야합니다. 나는이 같은 쿼리 빌더를 사용하여 문서의 데이터를 가져하려고하면 지금 users.is_suspendedyes 동일하다는 가정 :Laravel의 Eloquent ORM 대 쿼리 작성기

// first code: 

    $articles = Article::join('users', 'articles.user_id', '=', 'users.user_id') 
     ->select(['articles.*', 'users.user_name', 'users.user_email']) 
     ->where('articles.article_id', '=', 9) 
     ->where('articles.is_published', '=', 1) 
     ->where('users.is_suspended', '=', 'no') 
     ->get(); 

이 완벽하게 작동하며 (users.is_suspended = yes 때문에) 아무 것도 반환하지 않습니다. 이 기사도 사용자가 경우의 데이터를 가져옵니다

[ 
    { 
    article_id: 9, 
    user_id: 1, 
    article_title: "Article title here", 
    article_body: "Article body here", 
    is_published: 1, 
    created_at: "2015-01-17 02:26:24", 
    updated_at: "2015-01-17 02:26:24", 
    user: null 
    } 
] 

: 나는 다음의 결과를 얻을 것이다이 경우

// second code: 

$articles = Article::with([ 
    'user' => function($query) { 
     $query->select(['user_id', 'user_name', 'user_email']) 
      ->where('users.is_suspended', '=', 'no'); 
    }]) 
    ->where('articles.article_id', '=', 9) 
    ->where('articles.is_published', '=', 1) 
    ->get(); 

: 이제 같은 이런 Laravel 웅변 ORM과 기사를 가져 해보자 일시 중지되었습니다. 잘못된 것입니다. 그래서 내 질문에 첫 번째 코드처럼 행동하는 두 번째 코드를 수정하려면 어떻게됩니까?

답변

2

게으른로드 관계를 확인하기 위해 with을 사용하고 있지만로드 한 관계에만 적용되는 제약 조건이 적용될 수 있습니다. 사용자가 일시 중지되지 않은 기사에 대한 응답을 제한하려면 whereHas 메서드를 사용하는 것이 좋습니다. @DavidBarker 말한 것처럼

$articles = Article::with(['user' => function($q){ 
     $q->select(['user_id', 'user_name', 'user_email', 'created_at']); 
    }]) 
    ->whereHas('user', function($q) { 
     $q->where('is_suspended', '=', 'no'); 
    }) 
    ->where('articles.article_id', '=', 9) 
    ->where('articles.is_published', '=', 1) 
    ->get(); 
+0

그러나 어떻게 특정 열을 선택할 수 있으며 select ([ 'user_id', 'user_name', 'user_email'])를 어디에 넣어야합니까? $ q-> select ([ 'user_id', 'user_name', 'user_email', 'created_at']) -> 여기서 ('is_suspended', '=', 'no'); 하지만 오류가 발생합니다 : (카디널리티 위반 : 1241 피연산자는 4 개의 열을 포함해야합니다.) – Amr

+0

'with' 메소드 콜백에 ​​원래 위치에 넣었습니다. –

+0

오류가 발생합니다 : explode()는 매개 변수 2가 주어진 문자열 인 것으로 예상합니다. – Amr

0

당신은 whereHas 대신 with (또는 둘 다,하지만이 경우 with 필요 없음)가 필요합니다.

그러나 나는 더 많은 제안이 코드의 가독성을 고려 :

$article = Article::whereHas('user', function ($q) { 
    $q->active(); 
})->published()->find(9); 

그것은 scopes 사용합니다을.

$user->is_suspended; // no 
(bool) $user->is_suspended; // true  
  • ArticleUser 모델과 published에 범위를 suspended 정의 : 때문에 bool

    1. 변경 is_suspended :

      그래서 여기에 당신이 당신의 인생을 더 쉽게하기 위해 무엇을 할 수

      // Article model - on User accordingly 
      public function scopePublished($query) 
      { 
          $query->where('is_published', 1); 
      } 
      
    2. 단일 모델을 가져 오려면 get 대신 find($id) 또는 where('col', $id)->first()을 사용하십시오. 이는 후자가 결과를 하나만 남겼지 만 컬렉션을 반환하기 때문입니다.