2015-04-08 2 views
4

Я пытаюсь получить доступ к атрибуту Eloquent с Twig in Slim и получить сообщение об ошибке.Не удается получить доступ к атрибутам Eloquent на Twig

У меня есть поле и тип объекта, и соотношение выглядит следующим образом

class Field extends \Illuminate\Database\Eloquent\Model { 

protected $table = 'fields'; 

public function type() 
{ 
    return $this->belongsTo('models\Type'); 
} 

При выполнении {{ f }} (будучи метрономы поле), то выход таков:

{"field_id":"1","field_name":"Your name","form_id":"2","type_id":"1","placeholder":"Please give us your name"} 

И когда делать {{ f.type }}, результат:

Сообщение: Исключение было сделано во время рендеринга шаблона («Объект класса Осветите \ Database \ Eloquent \ Отношения \ BelongsTo не может быть преобразован в строку») в «страницах/editform.html» в строке 97.

Если я пытаюсь сделать {{ f.type.name }}, не выдает исключение, но ничего не печатает.

Если я делаю это в PHP

$fields = $form->fields; 
    var_dump($fields[0]->type->name); 

значение получает выход правильно.

Любые идеи ?, Благодаря

+0

Я действительно не знаю ветки, но по какой-то причине она, по-видимому, вызывает функцию, а не позволяет Ларавелу сделать это волшебство. Вы можете попробовать следующее: '{{f.type.name.get()}}' – lukasgeiter

+0

Не работает, сейчас мне пришлось прибегнуть к этому: 'public function getTypeString() {$ type = Тип: : найти ($ this-> tYPE_ID); return $ type-> name; } ' –

ответ

5

У меня был один и тот же вопрос и наткнулся на этот вопрос. Сам решив, я подумал, что попробую помочь тебе.

Попробуйте делать нетерпеливые нагрузки на модели:

Field::with('type')->get() 

Это позволит вам выполнять следующие операции без каких-либо других вопросов.

{{ f.type }} 

Смотреть подробнее здесь: http://laravel.com/docs/4.2/eloquent#eager-loading

+0

Работал, как шарм, интересная концепция, чтобы учиться, большое вам спасибо! –

+0

Теперь я понял! Спасибо, парни. – Pathros

7

Проблема заключается во взаимодействии между тем, как Eloquent реализует «динамическое свойство» для отношения (в вашем случае, f.type), а также правила, которые использует Twig для доступ к «атрибутам» переменной.

Из документации Twig:

ради удобства foo.bar делает следующие вещи на PHP слой:

  • проверить, если foo является массивом и bar действительный элемент;
  • если нет, и если foo является объектом, проверить, что bar является действительной собственности;
  • Если нет, и если foo является объектом, проверьте, что bar является допустимым методом (даже если bar является конструктором - вместо этого используйте __construct());
  • если нет, и если foo является объектом, проверьте, что getBar - действительный метод;
  • если нет, и если foo является объектом, убедитесь, что isBar - действительный метод;
  • если нет, верните нулевое значение.

foo['bar'] с другой стороны работает только с PHP массивы:

  • проверить, если foo массив и bar действительный элемент;
  • если нет, верните нулевое значение.

Ключевым моментом здесь является та часть, где он говорит: «проверить, что бар является допустимым свойством». Это означает, что на уровне PHP Twig вызывает isset на $f->type. Eloquent implements the magic __isset method in Model, так что вы можете подумать, что это не проблема.

Однако, посмотрите на то, как он на самом деле реализует __isset для модели отношений:

/** 
* Determine if an attribute exists on the model. 
* 
* @param string $key 
* @return bool 
*/ 
public function __isset($key) 
{ 
    return (isset($this->attributes[$key]) || isset($this->relations[$key])) || 
      ($this->hasGetMutator($key) && ! is_null($this->getAttributeValue($key))); 
} 

Он определяет, является ли отношение «установить», глядя в массив нагруженных отношений (isset($this->relations[$key])). Проблема в том, что если type еще не был загружен, Eloquent скажет, что он не «установлен».

Таким образом, когда Прут смотрит на $f->type, он будет думать, что type не является допустимым свойство и перейти к следующему правилу:

... если foo является объектом, убедитесь, что bar является допустимым методом

Так что теперь он будет искать методtype(), который он находит. Единственная проблема? type() (метод) возвращает Relation (в частности, BelongsTo), а не объект Type. И BelongsTo объекты не модели.

Если вы хотите Twig знать, что свойство $f->type действительно существует, у вас есть два варианта:

  • Вы можете нетерпеливые нагрузки на связанную Type объекта вместе с Field, как это было предложено @ Роджер-Коллинз , или;
  • Вы можете перегрузить метод __isset магии Field:

public function __isset($name) { if (in_array($name, [ 'type' ])) { return true; } else { return parent::__isset($name); } }

Это заставит Twig признать, что type является допустимым свойством для Field, еще до того, на самом деле была загружена соответствующая модель.

+0

Отличный ответ, спасибо, спасибо! –

+0

FYI, маленькая опечатка в коде 'isset'. Отсутствует ')' после 'type':'])) {' –

+0

спасибо, исправил это! – alexw

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