Как я могу издеваться над другой моделью, чтобы получить полиморфные отношения?

У меня есть 3 модели данных, одна из которых расширяет другую:

namespace AppModels;

use IlluminateDatabaseEloquentModel;

class Opinion extends Model
{
    public function reactions()
    {
        return $this->morphMany('AppModelsReaction', 'reactable');
    }

    ...
}
namespace AppModelsActivity;

use AppModelsOpinion;

class ActivityOpinion extends Opinion
{
    ...
}
namespace AppModels;

use IlluminateDatabaseEloquentModel;

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

    ...
}

Модель AppModelsOpinion имеет полиморфную связь с моделью AppModelsReaction . Я не могу получить все реакции AppModelsOpinion без проблем, так что я знаю, что отношения прекрасно работают.

У меня вопрос, как я могу получить тот же набор реакций из модели AppModelsActivityActivityOpinion ? Потому что сейчас он ищет AppModelsActivityActivityOpinion в качестве отношений, но мне нужно, чтобы он искал AppModelsOpinion . Можно ли издеваться над другой моделью в полиморфных отношениях?

Всего 1 ответ


Это связано с тем, что в полиморфных отношениях в хранимых данных (если оставить значение по умолчанию) тип отношения получает пространство имен класса (своего рода) для указания, какую модель необходимо вернуть. Вот почему, когда вы пытаетесь получить доступ к своим отношениям reactions() из ActivityOpinion он ищет значение AppActivityOpinion в reactable_type .

Вы можете настроить класс morph для поиска в модели:

Opinion.php

protected $morphClass = 'reaction'

Этого должно быть достаточно, если нет, добавьте его также в модель ActivityOpinion .


Заметка

Это может привести к ошибкам при попытке поиска результатов с помощью Eloquent. Проверьте , чтобы устранить это возможное неудобство.



Обновить

Я только что узнал, что вы можете сделать все это еще проще с MorphMap . Из документов:

Пользовательские Полиморфные Типы

По умолчанию Laravel будет использовать полное имя класса для хранения типа связанной модели. Например, учитывая приведенный выше пример «один ко многим», где Comment может принадлежать записи или Video , тип commentable_type по умолчанию будет соответственно AppPost или AppVideo, . Однако вы можете отделить базу данных от внутренней структуры вашего приложения. В этом случае вы можете определить «карту морфинга», чтобы дать Eloquent команду использовать произвольное имя для каждой модели вместо имени класса:

use IlluminateDatabaseEloquentRelationsRelation;

Relation::morphMap([
    'posts' => 'AppPost',
    'videos' => 'AppVideo',
]);

Вы можете зарегистрировать morphMap в функции boot вашего AppServiceProvider или создать отдельного поставщика услуг, если хотите.


Есть идеи?

10000