Я использую Laravel 5.1. Сценарий выглядит следующим образом (это пример. Реальный сценарий похож на этот пример)
У меня 3 модели
В колледже может быть много студентов, но студент может принадлежать только одному колледжу.
В колледже может быть много учителей, но учитель может принадлежать только одному колледжу.
Я хочу установить отношения между этими таблицами в laravel.
Одним из методов для этого является размещение college_id внешний ключ на столе студентов и преподавателей. Но в моем случае этот внешний ключ будет много раз нулевым. Поэтому вместо того, чтобы иметь отдельные столбцы в 3-4 таблицах с в основном нулевыми значениями, я хотел изучить возможность иметь полиморфные отношения для таблицы College.
Вот что я попробовал:
Пример, приведенный в документах laravel (ссылка ниже), изображает отношение один-ко-многим, в то время как мой сценарий — это скорее отношение многие-к-одному.
http://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations
Как показано в примере, наличие столбцов Collegeable_id и collegeable_type в таблице College не соответствовало бы моему требованию, поскольку в колледже может быть много студентов / преподавателей, поэтому я создал сводную таблицу:
Schema::create('collegeables', function (Blueprint $table) {
$table->integer('college_id')->unsigned();
$table->integer('collegeable_id')->unsigned();
$table->string('collegeable_type');
});
И у меня есть следующие модели
Модель колледжа:
namespace App;
use Illuminate\Database\Eloquent\Model;
class College extends Model
{
public function students()
{
return $this->morphedByMany('App\Student', 'collegeable');
}
}
Модель студента:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
public function college()
{
return $this->morphOne('App\Colleges', 'collegeable');
}
}
Благодаря этой схеме я могу хранить студентов, используя экземпляр модели College, как это
$college = \App\College::find(1);
$student = new \App\Student;
$student->name = 'John Doe';
$college->students()->save($student);
Но когда я пытаюсь получить экземпляр модели College, используя экземпляр модели Student, как указано ниже, это выдает мне ошибку:
public function index()
{
return \App\Student::find(1)->college;
}
SQLSTATE [42S22]: Столбец не найден: 1054 Неизвестный столбец ‘colleges.collegeable_id’
Это как бы ожидаемо, так как morphOne работает со столбцами в таблице, я полагаю.
Если я изменю функцию morphOne в модели студента на morphToMany, код начнет работать, и я также смогу извлечь значения. Но это делает эти отношения многими ко многим, что опять-таки не то, что я хочу.
Итак, мой вопрос заключается в следующем:
Является ли их функция morphSomething, которую я могу использовать в модели студента, чтобы иметь возможность извлекать значения для колледжа студента, поддерживая отношения как один-ко-многим?
Любая помощь могла бы быть полезна. Благодарю.
Там нет причин использовать полиморфные отношения здесь. Вместо этого просто добавьте внешний ключ к вашему colleges
стол на обоих ваших students
а также teachers
столы. Как это:
colleges
id
name
teachers
id
name
college_id
students
id
name
college_id
Тогда ваши модели могут использовать belongsTo()
а также hasMany()
отношения, вот так:
class College extends Model {
public function students() {
return $this->hasMany(App\Student::class);
}
public function teachers() {
return $this->hasMany(App\Teacher::class);
}
}
class Teacher extends Model {
public function colleges() {
return $this->belongsTo(App\College::class);
}
}
class Student extends Model {
public function colleges() {
return $this->belongsTo(App\College::class);
}
}
Полиморфные отношения «один ко многим» предназначены для противоположности этого отношения, когда у вас есть модель, которая может быть связана только с одной записью, но эта запись может быть множеством разных моделей.
Изменить: Чтобы далее объяснить, почему полиморфные отношения здесь не нужны, давайте посмотрим, где они были бы необходимы. Скажем, у вас есть простой веб-сайт в стиле CRM. Есть клиенты и проекты, и вы хотите иметь комментарии на оба. В этом случае вы бы сделали Комментарии полиморфными отношениями, потому что комментарии принадлежат одному Заказчику или одному Проекту, но не обоим.
Ваши отношения с точностью до наоборот. В вашем случае студенты и преподаватели принадлежат к колледжу. Если бы вы следовали шаблону предыдущего примера, колледж принадлежал бы одному ученику или учителю.
Других решений пока нет …