#laravel #eloquent #relationship #union
#laravel #красноречивый #отношения #объединение
Вопрос:
Я хочу получить всех пользователей из группы. Проблема в том, что в этой группе они являются пользователями-студентами (со сводной таблицей) и обычными пользователями. Итак, я должен объединить их вместе, но я все еще хочу сохранить все возможности eloquent. Я пришел к этому:
dd($this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'))->get());
Мои отношения с базой данных
Users
- id
Group
- id
Students
- id
- user_id (fk to users)
- class_id (fk to groups)
User_Group
- user_id (fk to users)
- group_id (fk to groups)
Пользовательская модель:
public function students()
{
return $this->hasMany(Student::class);
}
public function groups()
{
return $this->belongsToMany(Group::class);
}
Студент-модель
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function class()
{
return $this->belongsTo(Group::class, 'class_id');
}
Групповая модель
public function students()
{
return $this->hasMany(Student::class, 'class_id');
}
public function users()
{
return $this->belongsToMany(User::class);
}
public function members()
{
//this causes the problem!!
return $this->belongsToMany(User::class)->union($this->hasManyThrough(User::class,Student::class,'class_id','id','id','user_id'));
}
Комментарии:
1. Не ответ, но проблема здесь в том, что две стороны объединения не имеют одинакового количества / типа столбцов. Исправьте это, и ошибка должна исчезнуть.
2. Я знаю, но я не могу исправить это с помощью выбора только из таблицы users. *, я попробовал добавить с обеих сторон от объединения select(‘users. *’), но это не решило проблему.
3. Я заметил, что вы можете использовать ` DB::table(‘users’) ->join(‘groups’, function ($join) { $join-> on(‘users.id ‘, ‘=’, ‘group_user.user_id’)->orOn(‘студенты.class_id’, ‘=’, ‘groups.id ‘); })` Но это не решает сводные таблицы group_users и students
Ответ №1:
в пользовательской модели отношения
public function group(){
return $this->belongsToMany(Group::class);
}
в групповой модели отношения
public function user(){
return $this->belongsToMany(User::class, 'user_group');
}
в модели студентов отношения
public function user(){
return $this->belongsToMany(User::class, 'user_id', 'id');
}
public function group(){
return $this->belongsToMany(Group::class, 'class_id', 'id');
}
теперь вы можете вызвать
$users = User::whereHas('groups',function ($query){
$query->where('group_id',1);
})->get();
Комментарии:
1. Это не решает мою проблему, потому что я уже могу получать своих пользователей из определенного класса, я только не могу объединить их с пользователем, который напрямую связан с группой. Итак, класс — это группа, и пользователи могут быть связаны непосредственно с группой, а также с классом students с группой: итак, user -> group и user -> student (user_id, class_id) -> group, и из группы мне нужны пользователи, а также студенты,в красноречивой модели. я редактирую свой вопрос со всеми вещами, которые у меня уже есть в моих моделях
Ответ №2:
Иногда у вас есть два отношения из одной модели в другую из-за сводных таблиц. В моем примере вы могли бы перейти от пользователей к группам с отношением user_groups и отношением students . Чтобы получить всех пользователей, принадлежащих к определенной группе, мне нужно вызвать оба отношения. Чтобы решить эту проблему, я использовал пример Абдулмаджида для ее решения. Вы можете увидеть код ниже. Спасибо, что помогли мне.
public function members()
{
return User::whereHas('groups', function($q)
{
$q->where('id',$this->id);
})->orWhereHas('students', function($q)
{
$q->where('class_id',$this->id);
});
}