2016-01-09 2 views
2

Предположим, у меня есть имен таблиц MySQL и ряд ID:Laravel 5 Динамически создавать красноречивые Модели

['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 

Пожалуйста, дайте мне знать, если это недостаточно ясно.

EDIT:

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; 
    } 
} 
+1

Вы добавили 'use RevisionableTrait'' в свой класс' Dynamic'? 'lastRevision' - это отношения, добавленные этой чертой, поэтому, если ваш класс' Dynamic' не использует этот признак, он не будет иметь отношения. – patricus

+0

На самом деле я действительно забыл добавить черту к модели 'Dynamic', но отношения все равно не загружаются. Я думаю, что это может иметь какое-то отношение к Edit I, представленному в моем первоначальном вопросе. –

+0

Это потому, что 'find()' вернет новый экземпляр модели, который не будет иметь имя таблицы. Вам нужно будет сделать что-то вроде: '$ model = new Dynamic ([]); $ Модели-> отверждаемые ($ строки [ 'table_name']); $ model = $ model-> find ($ row ['row_id']); $ Модели-> отверждаемые ($ строки [ 'table_name']); $ revision = $ model-> latestRevision; ' – patricus

ответ

2

Во-первых, 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; 
+0

Спасибо, я тоже думал о втором подходе. –

+0

@JaredEitnier Нет проблем. Оба метода имеют свои плюсы и минусы. Второй метод будет иметь меньше «gotchas», но если вы когда-либо отклонились от соглашения об именах Laravel, код больше не будет работать. Рад, что я мог помочь. – patricus

+0

Я собираюсь придерживаться первого метода. Динамическое размещение имен моделей в Laravel 5 будет беспорядочным. –

Смежные вопросы