Модели:
Пользователь который имеет много групп и имеет много роли через группа
и
группа которая hasMany пользователи .
Эти отношения хранятся в таблице group в столбце с именем 'members', который отформатирован следующим образом:
[
{
user_id: *user_id_one*
role_id: *role_id_one*
},
{
user_id: *user_id_two*
role_id: *role_id_two*
},
]
Требования:
- Модели должны быть связаны через отношения, чтобы я мог их быстро загрузить.
- Я не могу изменить структуру данных, потому что очень большое количество программ уже было сделано в отношении этих моделей и структур.
- Это должно быть сделано с использованием sql версии от 5.7
- Это должно быть сделано с использованием php 7.1, 7.2 или 7.3
Что я пробовал:
Сначала я попробовал это в Пользователь модель:
method:
$this->hasMany('\App\Group', 'members->[*].user_id')
query:
select * from `groups` where json_unquote(json_extract(`groups`.`members`, '$."[*].user_id"')) = ? and json_unquote(json_extract(`groups`.`members`, '$."[*].user_id"')) is not null
Затем:
method:
$this->hasMany('\App\Group', 'members->[*].user_id')
or
$this->hasMany('\App\Group', 'members->$[*].user_id')
query:
Column Not Found
Могучие staudenmeir / eloquent- json -отношения приблизили меня к
method:
$this->hasManyJson('\App\Group', 'members->[*].user_id')
query:
select * from `groups` where json_contains(`groups`.`members`, ?, '$."[*].user_id"')
Все они были опробованы с использованием обычного первичного ключа и пользовательских атрибутов, которые возвращали:
- "JSON_ARRAY ( primary_key )"
- "JSON_OBJECT ('id', primary_key ) "
- " [' primary_key '] "
- " {'id': ' primary_key '} "
Однако все они были в кавычках.
Уже учтено:
Вот пример рабочего атрибута
public function getGroupsAttribute()
{
return Group::whereRaw("JSON_CONTAINS(members->'$[*].user_id', JSON_ARRAY('{$this->id}'))")->get();
}
Я подумала, прежде чем уйти и завела обычные отношения, которые я бы спросила здесь. Я мог бы, вероятно, сделать что-то с областью действия, чтобы применить что-то вроде следующего (с отношением, которое только что вернуло все группы), но это был бы тот же объем работы и менее чистый.
->with(['groups' => function ($query) use ($user) {
$query->whereRaw("JSON_CONTAINS(members->'$[*].user_id', JSON_ARRAY('{$user->id}'))")
}])