Laravel Красноречивые отношения между одной моделью и многими моделями как MorphOne?

Вступление:

У меня есть эти таблицы с их моделями:

  • таблица адресов -> модель адреса
  • таблица пользователей -> Модель пользователя
  • таблица компаний -> Модель компании
  • таблица свойств -> модель собственности

Правила:

  • у каждого пользователя может быть только один адрес.
  • у каждой компании может быть только один адрес.
  • у каждого объекта может быть только один адрес.

Здесь можно выполнить два возможных планирования отношений:

  • Пользователь hasOne Адрес и адрес принадлежит Пользователь [т.е. взаимно-однозначное отношение], но недостатком является то, что внешний ключ здесь находится в таблице адресов, то есть в поле ID пользователя, и, повторяя такое же отношение с другими моделями [Компания и Собственность], мы получим еще два внешних ключа в таблице адресов, которые равны [Идентификатор компании и property_id], тогда мы получим 3 внешних ключа для 3 моделей. Но запись только один будет заполнен каждой строкой всегда оставляет два поля внешних ключей пустыми.

    Я считаю, что это накладные расходы на таблицу адресов.

ИЛИ наоборот:

  • Адрес hasOne Пользователь и пользователь принадлежит Адрес [также взаимно однозначное отношение]. Это имеет то преимущество, что внешний ключ сохраняется здесь, в связанной модели, то есть [Пользователь, Компания и Свойство], таким образом, нет пустых полей внешних ключей --- Но все же это противоречит реальной логике моделирования, которая диктует, что Пользователь hasOne Адрес больше, чем Адрес hasOne User.

Мой вопрос:

Есть ли какие-либо другие отношения, которые могут связать эти 4 модели в одно отношение, подобное полиморфным отношениям, но без использования MorphMany, а вместо этого с использованием MorphOne, что, как ни странно, я не могу найти его в документации Laravel, хотя сам метод существует в Eloquent Relations.

Возможно ли это полиморфное отношение MorphOne и как оно составлено?

Существующий код:

//Address model
public function user(){
    return $this->hasOne(User::class);
}
public function company(){
    return $this->hasOne(Company::class);
}
public function property(){
    return $this->hasOne(Property::class);
}

//User model
public function address(){
    return $this->belongsTo(Address::class);
}

//Company model
public function address(){
    return $this->belongsTo(Address::class);
}
//Property model
public function address(){
    return $this->belongsTo(Address::class);
}

Как насчет того, чтобы сохранить поля идентификатора и типа в таблице адресов. Здесь идентификатор будет идентификатором из таблицы пользователя, компании или свойства, а тип будет хранить имя (пользователь / компания / свойство), которому принадлежит этот идентификатор. Как этого добиться, используя красноречие, я не уверен

Ganymede 11.06.2018 05:45

Вы можете сохранить поле типа как enum

Ganymede 11.06.2018 05:51

Я согласен с вами, поскольку это похоже на то, что я ищу в MorphOne Relationship. Но я бы использовал для этого Eloquent вместо того, чтобы делать это вручную - это нужно для того, чтобы воспользоваться преимуществами встроенных отношений Eloquent вместо того, чтобы я вручную создавал сеттеры и геттеры.

WillKoz 11.06.2018 05:54

Меня больше беспокоит построение отношений, чем хранение самих данных, поскольку я могу ограничить значения и типы хранилищ данных с помощью AddressController непосредственно в Laravel. То, что мне нужно, - это правильные отношения Eloquent между Address и другими 3 моделями User, Company и Property, чтобы использовать их в дальнейшем коде проекта.

WillKoz 11.06.2018 06:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
6
4
1 498
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот взаимосвязь в MorphOne между Адрес с одной стороны и Пользователь, Компания и Имущество с другой стороны:

class Address extends Model
    public function addressable(){
        return $this->morphTo();
    }       
}

class User extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable'); //note this is not MorphMany()
    }       
}

class Company extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable');
    }       
}

class Property extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable');
    }       
}

затем в UserController что-то вроде этого:

$user = User::find(1);

$addressData = [
    'street_name' => '5, Golf street',
    'country_id' => 100, //etc..
];

//to add new address record related to user:
$user->address()->create($addressData);
dd($user->address);

//to update existing address record related to user:
$user->address->update($addressData);
//dd($user->address);

Другие вопросы по теме