Как с помощью Laravel eloquent получить связаные данные таблиц?
Есть четыре таблицы characters, locations, character_classes и friends.
friends - хранит данные в виде пары id персонажей из таблицы characters
Как зная id персонажа максимально простым способом получить список друзей состоящий из столбцов characters.name, characters.gender, characters.level_id, characters.update_at, locations.name, character_classes.name?
Пытался чудить с джойнами, но максимум что получилось так это вытянуть список друзей персонажа состоящий исключительно из данных таблицы characters, без связных данных из других таблиц.
Я так понимаю тут нужно грамотно прописать связи в моделях. Из того что уже создал это связи для Characters
public function characterClass(): BelongsTo
{
return $this->belongsTo(CharacterClass::class);
}
public function location(): BelongsTo
{
return $this->belongsTo(Location::class);
}
и Location
public function characters()
{
return $this->hasMany(Character::class);
}
В миграции ключи для таблицы charactersвыглядят так
$table->unsignedInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
$table->uuid('location_id');
$table->foreign('location_id')->references('id')->on('locations')->onDelete('restrict');
$table->unsignedInteger('character_class_id');
$table->foreign('character_class_id')->references('id')->on('character_classes')->onDelete('restrict');
для таблицы character_classes
$table->uuid('starting_location_id');
$table->foreign('starting_location_id')
->references('id')
->on('locations')
->onDelete('restrict');
Больше никаких ключей не добавлял.
Ответы (2 шт):
Удалось получить нужные данные таким образом. Если есть варианты получше, буду рад посмотреть)
Character::rightJoin(
'friends',
function ($join) {
$join->on('friends.id_friend_one', '=', 'characters.id')
->orOn('friends.id_friend_two', '=', 'characters.id');
}
)
->where(
function ($query) use ($id) {
$query->where('friends.id_friend_one', '=', $id)
->whereRaw('friends.id_friend_two = characters.id');
}
)
->orWhere(
function ($query) use ($id) {
$query->whereRaw('friends.id_friend_one = characters.id')
->where('friends.id_friend_two', '=', $id);
}
)
->with(['location:id,name','characterClass:id,name'])
->skip($skip)
->take(15)
->get(['characters.id','characters.name','characters.gender','characters.location_id','characters.character_class_id','characters.level_id']);
Я не рекомендую использовать сырые запросы к бд это плохая практика, работа по отношениям во фреймворке легкая и непринужденная
Если я верно понял условия задачи и все отношения то вот ваше решение (внимательно названия методов в модели приведены к единственному числу и соответственно меняется вызов):
//связи для модели User
public function character(){
return $this->belongsTo(Character::class);
}
//связи для модели Character
public function character_class(){
return $this->belongsTo(СharacterClass::class);
}
//связи для модели СharacterClass
public function location(){
return $this->belongsTo(Location::class);
}
$user = User::find($id_friend_one);
$user->character->name;
$user->character->gender;
$user->character->level_id;
$user->character->update_at;
$user->character->character_class->name;
$user->character->character_class->location->name;
