Вам понадобится заглянуть в Полиморфные отношения в Laravel, чтобы достичь этого. Полиморфная связь позволит вам получить другую модель на основе поля типа . В вашей Slug
модели вам понадобится что-то вроде этого:
public function page()
{
return $this->morphTo('page', 'layout_id', 'id');
}
У одного из ваших поставщиков услуг, например, AppServiceProvider
вам потребуется предоставить Morph Map , чтобы Laravel отображал определенные идентификаторы в определенные классы моделей. Например:
Relation::morphMap([
1 => Page::class,
// ...
6 => ArticlePage::class,
]);
Теперь, когда вы используете отношение page
, Laravel проверит тип и вернет вам правильную модель.
Примечание: Я не уверен на 100% в параметрах и т. Д., И я не проверял, но вы должны быть в состоянии понять это из документов.
Если ваш layout_id
относится к модели Page
, единственное решение, которое я вижу, это добавить метод к вашей модели Page
, который способен преобразовать вашу существующую страницу в ArticlePage
или другой тип страницы, основанный на свойстве layout_id
. Вы должны быть в состоянии попробовать что-то вроде этого:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Page extends Model
{
const LAYOUT_ARTICLE = 6;
protected $layoutMappings = [
// Add your other mappings here
self::LAYOUT_ARTICLE => ArticlePage::class
];
public function toLayoutPage()
{
$class = $this->layoutMappings[$this->layout_id];
if (class_exists($class)) {
return (new $class())
->newInstance([], true)
->setRawAttributes($this->getAttributes());
}
throw new \Exception('Invalid layout.');
}
}
Что это делает, так это ищет отображение на основе вашего свойства layout_id
, а затем создает новый класс правильного типа, заполняя его атрибуты теми, которые вы создали на странице. Это должно быть все, что вам нужно, если вы посмотрите на метод Illuminate\Database\Eloquent::newFromBuilder()
Laravel, который Laravel вызывает при создании новых экземпляров модели, вы можете увидеть, что происходит и как я получил приведенный выше код. Вы должны иметь возможность просто использовать его так:
$page = Slug::where('slug', $slug)
->first()
->page
->toLayoutPage();
Это даст вам экземпляр ArticlePage