Проблема заключается во взаимодействии между тем, как 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
, еще до того, на самом деле была загружена соответствующая модель.
Я действительно не знаю ветки, но по какой-то причине она, по-видимому, вызывает функцию, а не позволяет Ларавелу сделать это волшебство. Вы можете попробовать следующее: '{{f.type.name.get()}}' – lukasgeiter
Не работает, сейчас мне пришлось прибегнуть к этому: 'public function getTypeString() {$ type = Тип: : найти ($ this-> tYPE_ID); return $ type-> name; } ' –