Laravel - 从相关查询中检索特定列

时间:2014-08-10 23:34:16

标签: laravel eloquent eager-loading

我有4张桌子:

conversations
- id (pk)
- userId1 (fk)
- userId2 (fk)

users
- id (pk)
- name
- surname
.
.
.
- roleId (fk)
- userStatusId (fk)

roles
- id (pk)
- type (fk)

user_status
- id (pk)
- description (fk)

这是我的模特:

    class Conversation extends Eloquent {

        public function user1(){
            return $this->hasOne('User', 'id', 'userId1');
        }

        public function user2(){
            return $this->hasOne('User', 'id', 'userId2');
        }

    }

    class User extends Eloquent {

        public function role(){
            return $this->hasOne('Role', 'id', 'roleId');
        }
        public function userStatus(){
            return $this->hasOne('UserStatus', 'id', 'userStatusId');
        }


        // public function conversation1(){
        //  return $this->belongsToMany('Conversation', 'id', 'userId1');
        // }
        // public function conversation2(){
        //  return $this->belongsToMany('Conversation', 'id', 'userId2');
        // }


    }

class UserStatus extends Eloquent {

    public $timestamps = false;
    protected $table = 'user_status';

    public function user(){
        return $this->belongsToMany('User', 'id', 'userStatusId');
    }

}

class Role extends Eloquent {

    public $timestamps = false;

    public function user(){
        return $this->belongsToMany('User', 'id', 'roleId');
    }

} 

现在我要做的是,例如,将“userId1”(对话)是“用户”的所有对话,其“状态”描述“等于”已注册“。

这就是我的所作所为:

Route::get('/', function(){
    $conversation = Conversation::with(array('user1.userStatus' => function ($query){
        $query->where('description', '=', 'registered');
    }))->get();
    foreach ($conversation as $conv) {
        echo '<br \>';
        echo $conv;
    }
});

我希望收到所有会话记录,其中userId1的状态为“已注册”,而不是其他任何内容...而是我收到的是所有会话记录,并且对于每个会话记录,用户记录和记录userStatus表(最后我只接收匹配where子句的那个和没有空值的那个)。

我知道我的英语很糟糕,但我希望有人能理解并帮助我。谢谢!

2 个答案:

答案 0 :(得分:0)

你可以试试这个:

$conversations = Conversation::whereHas('user1.userStatus', function ($query){
    $query->where('description', '=', 'registered');
})->get();

这将只返回相关Conversationuser1.userStatus的{​​{1}}个模型。

答案 1 :(得分:0)

你们所有的关系都错了。您需要阅读http://laravel.com/docs/eloquent#relationships,在您的情况下,请阅读

class Conversation extends Eloquent {

    public function user1(){
        return $this->belongsTo('User', 'userId1');
    }

    public function user2(){
        return $this->belongsTo('User', 'userId2');
    }

}

class User extends Eloquent {

    public function role(){
        return $this->belongsTo('Role', 'roleId');
    }
    public function userStatus(){
        return $this->belongsTo('UserStatus', 'userStatusId');
    }
}

class UserStatus extends Eloquent {

    public $timestamps = false;
    protected $table = 'user_status';

    public function user(){
        return $this->hasMany('User', 'userStatusId');
    }

}

class Role extends Eloquent {

    public $timestamps = false;

    public function user(){
        return $this->hasMany('User', 'roleId');
    }

}

现在,只检索您想要的对话

Conversation::whereHas('user1', function ($q) {
  $q->whereHas('userStatus', function ($q) {
    $q->where('description', 'registered');
  });
})->get();

或使用此PR https://github.com/laravel/framework/pull/4954

Conversation::whereHas('user1.userStatus', function ($q) {
  $q->where('description', 'registered');
})->get();

另外,为了使它更详细,您可以将该代码包装在范围内:

// User model
public function scopeRegistered($query)
{
  $q->whereHas('userStatus', function ($q) {
    $q->where('description', 'registered');
  });
}

然后:

Conversation::whereHas('user1', function ($q) {
  $q->registered();
})->get();