在使用聊天应用程序时,我已经看了很多时间了,但是我似乎无法理解如何实现以下目标:
我所拥有的: 3张桌子:
客户
频道
channel_client(数据透视表)
2种型号:
App \ Clients
class Client extends Model
{
protected $table = "clients";
public function channels() {
return $this->belongsToMany(Channel::class);
} ...
应用程序\频道
class Channel extends Model
public function clients() {
return $this->belongsToMany(Client::class);
} ...
我想要实现的目标: 获取包含客户端X和客户端Y以及其他任何内容的频道。 (我可以通过客户端模型预先访问客户端ID)
我尝试了一下修改,结果如下:
>>> $client = App\Client::with('channels')->whereIn('id',[1,2])->get()
=> Illuminate\Database\Eloquent\Collection {#3303
all: [
App\Client {#3243
id: 1,
name: "John",
user_id: 1,
created_at: "2019-08-14 12:55:19",
updated_at: "2019-08-14 12:55:19",
channels: Illuminate\Database\Eloquent\Collection {#3354
all: [
App\Channel {#3249
id: 1,
name: "Web Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3362
client_id: 1,
channel_id: 1,
},
},
App\Channel {#3360
id: 3,
name: "iOS Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3321
client_id: 1,
channel_id: 3,
},
},
App\Channel {#3363
id: 5,
name: "Android Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3329
client_id: 1,
channel_id: 5,
},
},
],
},
},
App\Client {#3283
id: 2,
name: "Lucy",
user_id: 2,
created_at: null,
updated_at: null,
channels: Illuminate\Database\Eloquent\Collection {#3286
all: [
App\Channel {#3364
id: 1,
name: "Web Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3248
client_id: 2,
channel_id: 1,
},
},
],
},
},
],
}
>>>
正如您在此处看到的那样,ID为1的频道是用户的相互频道,因为用户1和用户2都订阅了频道1。
我知道我的查询会返回所有用户及其用户ID为1或2的频道,但是如果我将其转过来并查询App \ Channel :: with('users')...我无法指定位置子句,因为我不知道这是相互的频道ID。这就是我要尝试查询的内容。 所以这是总结: 我想要一个 Eagerloading Query (否则,我将使用whereHas),它返回我指定的客户的相互渠道。 非常感谢您的阅读。 我希望您能帮助我理解这一点。 问候!
编辑:因此,按This Laravel Documentation Part判断,它应该按照@Mohamed Ahmed的描述工作,但是当我尝试时,我得到以下结果,其中似乎已加载了所有通道,但也加载了我指定的客户端(但仍然查询所有频道,这不是我真正的目标)
>>> $cha = App\Channel::with(['clients' => function($q){ $q->whereIn('id',[1,2]); }])->get();
=> Illuminate\Database\Eloquent\Collection {#3359
all: [
App\Channel {#3365
id: 1,
name: "Web Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
clients: Illuminate\Database\Eloquent\Collection {#3403
all: [
App\Client {#3398
id: 1,
name: "John Doe",
user_id: 1,
created_at: "2019-08-14 12:55:19",
updated_at: "2019-08-14 12:55:19",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3324
channel_id: 1,
client_id: 1,
},
},
App\Client {#3240
id: 2,
name: "Lucy",
user_id: 2,
created_at: null,
updated_at: null,
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3372
channel_id: 1,
client_id: 2,
},
},
],
},
},
App\Channel {#3325
id: 2,
name: "Android Development",
type: null,
created_at: "2019-08-14 12:52:32",
updated_at: "2019-08-14 12:52:32",
clients: Illuminate\Database\Eloquent\Collection {#3268
all: [],
},
},
... all the remaining channels here (too much code)
所以这是部分正确的。有想法吗?
答案 0 :(得分:0)
您绝对可以扭转它。但这将意味着要修补(得到双关语?)。
您要做的是访问Channel模型并执行whereHas('users')
。魔术发生在这里:
$channel = App\Channel::whereHas('clients', function($q){
$q->whereIn('id', [1,2])->get();
})->get()
您可以在控制器中尝试此操作或将其作为返回值。
这基本上是做的,它称为clients
关系并在该关系内运行条件。如果您正确设置了关系(正确设置了许多与数据透视表的关系),则应该没有任何其他问题。因此,现在上面的代码将采用所有ID为1和2的客户端的渠道。
希望这会有所帮助。
快乐编码:)