Twig - как изначально отображать отношения RedBean внутри шаблона?

Я пытаюсь заставить symfony Twig хорошо работать с RedBean.

Я могу отобразить данные bean-компонента верхнего уровня, но ни одно из его отношений.

Вот что я имею в виду:

В моем контроллере я вызываю Twig стандартным образом (несколько псевдокод):

// Controller
$vars = array(
    'people' = R::find('person')
);

return $this->app['twig']->render('index.twig',$vars);

Мои бобы структурированы следующим образом:

PERSON
->id
->first_name
->last_name
->company <-- (this represents a 'company' bean)

COMPANY
->id
->name

Внутри index.twig я могу легко вывести имя человека вот так...

{% for person in people %}
    {{person.first_name}}
{% endfor %}

... но то, что я ХОЧУ получить, - это ассоциированный компонент компании, например...

{% for person in people %}
    **{{person.company.name}}**
{% endfor %}

Как мне сделать это внутри шаблона ветки, не требуя дополнительной логики контроллера/модели?


person Lee Benson    schedule 06.03.2012    source источник
comment
Я не пробовал RedBeans внутри S2, но похоже, что это сработает. Убедитесь, что команда echo $person-›company-›name дает ожидаемый результат. Возможно, что ваши отношения не правильно настроены?   -  person Cerad    schedule 06.03.2012
comment
Внутри контроллера он работает, как и ожидалось... т. е. echo $person-›company-›name работает нормально. Просто внутри файла TWIG этого нет. Я даже настроил фильтр print_r ({{person|print_r}}), и шаблон ветки правильно идентифицирует переменную «person» как объект RedBean_OODBBean... но person.company появляется как null. Очень странно!   -  person Lee Benson    schedule 06.03.2012
comment
Twig работает, ища фактические данные экземпляра или имена методов. RedBeans скрывают это за магическими методами. Вы можете попробовать добавить собственный метод getCompany() redbeanphp.com/manual/custom_getters, но я этого не делаю. Не думаю, что это поможет. Я не вижу решения, кроме как обернуть компонент person в какой-то объект доступа.   -  person Cerad    schedule 06.03.2012
comment
@Cerad - отличное предложение, которое действительно сработало отлично! Я просто добавил метод getCompany() в bean-компонент и вернул $this-›company внутри метода. Чтобы вызвать его, теперь требуется просто {{person.getCompany().name}} — не совсем так чисто и требует явных методов, но, по крайней мере, это работает... спасибо Cerad!   -  person Lee Benson    schedule 06.03.2012


Ответы (3)


Это показывает основную проблему:

protected function testQuery()
{
    $persons = \R::find('personx');
    foreach($persons as $person)
    {
        //$person->company;

        if ($person instanceof \ArrayAccess && isset($person['company']))
        {
            echo 'Got Array' . "\n";
        }
        echo get_class($person) . ' ' . $person->name . ' ' . $person->company->name . "\n";
    }
}

Происходит то, что компания лениво загружается, когда вы делаете $person->company. Twig проверяет наличие свойства компании, прежде чем пытаться его загрузить, и не находит его. Если раскомментировать строку $person->company, то тест пройден и все будет хорошо.

Я не видел в RedBeans ничего, что позволяло бы нетерпеливую загрузку. Вы можете запустить свой контроллер и просто вызвать $person->company для каждого человека. Или вы можете попробовать возиться с Twig_Template::getAttribute(); Или, может быть, даже использовать запросы и работать с массивами.

person Cerad    schedule 06.03.2012

Простите мой некропостинг, но это единственная страница в Интернете, посвященная этой проблеме, и я думаю, что у меня есть более элегантное решение, чем принятый ответ (что, возможно, было невозможно на момент публикации вопроса).

Я понимаю, что OP не хотел создавать дополнительную функциональность модели, но это решение состоит как минимум из 4 строк, так что не так уж много работы.

Я создал оболочку модели для своего bean-компонента, а затем сослался на связанный bean-компонент в методе open(). open() вызывается автоматически, когда R::load() вызывается для связанной таблицы. Итак, для ситуации OP модель будет выглядеть так:

class Model_Person extends RedBean_SimpleModel{
    public function open(){
        $this->ownCompany;
    }
}

Простая ссылка на ownCompany запускает ленивую загрузку, которая теперь позволяет Twig получить доступ к свойству.

person Quasipickle    schedule 09.11.2014
comment
Так $person-›open() где-то вызывается автоматически? Я не смотрел на redbean с момента первоначального поста. Просто любопытно. - person Cerad; 11.11.2014
comment
Да, open() вызывается всякий раз, когда R::load() вызывается для связанной таблицы. Я обновил свой ответ, чтобы прояснить это. - person Quasipickle; 11.11.2014
comment
это идеально подходит для моих целей, спасибо! больше нигде ничего не нашел. - person Laura; 06.12.2016

Попробуй это:

{% for person in people %}
    **{{person.__get('company').name}}**
{% endfor %}
person Benoit Pruneau    schedule 01.05.2017