Предположим, у меня есть имена таблиц mysql и идентификатор строки:
['table_name' => 'things', 'row_id' => 11],
['table_name' => 'stuff', 'row_id' => 5]
Каждая из этих таблиц имеет Eloquent
модель со ссылкой на таблицу. Как я могу перебрать список и динамически использовать Модель для создания нового экземпляра из table_name
ключ и find
строка на основе row_id
ключ?
Я могу получить нужные мне данные через Builder
экземпляр, но мне действительно нужно построить Model
пример. Это потому, что я реализую контракт через Eloquent
модель и ищет конкретный атрибут из этого контракта. Я не могу получить атрибут через экземпляр Builder.
(Пакет, который я использую: https://github.com/jarektkaczyk/revisionable. Я реализую Revisionable
на моделях)
Чтобы уточнить немного, это работает:
dd(\App\Models\Thing::find(11)->latestRevision); // returns Revision model
Пока этого нет:
// foreach($rows as $row)
$model = new Dynamic([])->setTable($row['table_name']);
dd($model->find($row)); // returns model with correct data
dd($model->find($row['row_id'])->latestRevision); // returns null
// endforeach
Пожалуйста, дайте мне знать, если это не достаточно ясно.
РЕДАКТИРОВАТЬ:
dd($model->find($row)); // returns model with correct data but shows table as `null` as if it isn't being persisted across the request.
Кроме того, вот Dynamic
модель:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Sofa\Revisionable\Laravel\RevisionableTrait;
use Sofa\Revisionable\Revisionable;
class Dynamic extends Model implements Revisionable
{
use RevisionableTrait;
/**
* @param $table
*/
public function __construct($attributes = [])
{
parent::__construct($attributes);
}
/**
* Dynamically set a model's table.
*
* @param $table
* @return void
*/
public function setTable($table)
{
$this->table = $table;
return $this;
}
}
Первый, latestRevision
это отношения, добавленные RevisionableTrait
так что вам нужно убедиться, что ваш Dynamic
класс имеет use RevisionableTrait;
заявление.
Далее, так как find()
Метод (и любые другие методы поиска) возвращают новые экземпляры моделей, вам нужно будет снова сбросить таблицу для каждой модели после ее обнаружения. Итак, ваш код будет выглядеть примерно так:
$model = new Dynamic([]);
$model->setTable($row['table_name']);
$model = $model->find($row['row_id']);
$model->setTable($row['table_name']);
$revision = $model->latestRevision;
Другой вариант, если вы будете следовать соглашениям об именах Laravel, состоит в том, что вы можете определить Model
имя из table_name, и просто используйте правильное Model
с самого начала, вместо этого Dynamic
модель:
$modelName = Str::studly(Str::singular($row['table_name']));
$model = $modelName::find($row['row_id']);
$revision = $model->latestRevision;
Других решений пока нет …