Какие отношения между таблицами Laravel лучше использовать в данном случае?
Таблица Profiles:
id name:
1 Olga,
2 Marina,
3 Zina
Таблица Languages:
id title
1 Немецкий,
2 Русский
Как правильно реализовать связи между таблицами если в Profile нам нужно получить не просто язык Немецкий,Русский или оба вместе для каждого профиля но и уровень от 1-6?
Нужно ли создать таблицу Level и привязать к Languages или как правильнее?
В профиле выбирается язык и его уровень. Сохранять всё в одну или разные таблицы?
То есть с HTML кода что ниже при выборе к примеру 1 языка
мы получаем Id profile, id Language и Level
Если создать таблицу такую ?
profile_id language_id level
1 2 5
@foreach(App\Language::all() as $language)
<div class="form-group language-block col-md-12 ">
<div class="col-md-6">
<input onchange="language_level(4860,'language');" id="language_{{$language->id}}" class="languages" type="checkbox" name="language[]" value="{{$language->id}}">
<label class="lang-label" for="language_{{$language->id}}">{{$language->title}}</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="1" checked="" disabled>
<label for="">1</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="2" disabled >
<label for="">2</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="3" disabled>
<label for="">3</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="4" disabled>
<label for="">4</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="5" disabled>
<label for="">5</label>
</div>
<div class="lang-radio col-md-1">
<input type="radio" id="" onchange="language_level(4860,'language');" name="lang-level-{{$language->id}}" value="6" disabled>
<label for="">6</label>
</div>
</div>
@endforeach
Спасибо
Ответы (2 шт):
Я бы разделил на 5 таблицы:
Profiles- непосредственно профиль пользователя;Languages- доступные языки в системе;Levels- доступные уровни;Language Levels- уровни знания языка;Profile Languages- взаимосвязь между пользователем языком и его уровнем.
Модель Profile:
class Profile extends Model {
/**
* @return HasMany
*/
public function profile_languages(): HasMany {
return $this->hasMany(ProfileLanguage::class);
}
/**
* @return HasManyThrough
*/
public function languages(): HasManyThrough {
return $this->HasManyThrough(LanguageLevel::class,ProfileLanguage::class, 'profile_id', 'id', 'id', 'language_level_id');
}
}
Модель LanguageLevel
class LanguageLevel extends Model {
/**
* @return HasOne
*/
public function language(): HasOne{
return $this->HasOne(Language::class, 'id', 'language_id');
}
/**
* @return HasOne
*/
public function level(): HasOne{
return $this->HasOne(Level::class, 'id', 'level_id');
}
}
Пример выборки: App\Profile::with('languages.level')->find(1) и её результат:
Если пользоваться стандартами Laravel, то здесь вырисовывается следующая схема:
Profiles -> Languages -> manyToMany
Languages -> Levels -> manyToMany (но это необязательная связь, при втором решении).
Тут соответственно напрашиваются уже 5 таблиц:
- profiles
- languages
- levels
- language_level поля id, language_id, level_id
- language_user (по алфавиту наименование) с полями profile_id, language_level_id
Но это, если следовать всем нормальным формам БД и соблюдать атомарность таблиц.
Есть и второй вариант с 4 таблицами:
- profiles
- languages
- levels
- language_user с полями profile_id, language_id, level_id
Но второй вариант подразумевает "хвостик" во всех запросах withPivotParams, иначе не будет браться level_id
Ну а так решать Вам)

