Lee Benson
Lee Benson

Reputation: 11599

Twig - how to natively display RedBean relationships inside template?

I'm trying to get symfony's Twig to play nicely with RedBean.

I can display a top-level bean's data, but none of its relationships.

Here's what I mean:

In my controller, I'm calling Twig in a standard way (somewhat psuedo code):

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

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

My beans are structured as follows:

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

COMPANY
->id
->name

Inside index.twig, I can easily output the person's name like this...

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

... but what I WANT to be able to access is the associated company bean, like this...

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

How do I do that from inside a twig template without requiring additional controller/model logic?

Upvotes: 2

Views: 1263

Answers (3)

Benoit Pruneau
Benoit Pruneau

Reputation: 11

Try this:

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

Upvotes: 1

Quasipickle
Quasipickle

Reputation: 4498

Forgive my necro-posting, but this is the only page on the Internet about this problem, and I think I have a more elegant solution than the accepted answer (which may not have been possible at the time the question was posted).

I realize the OP didn't want to create extra model functionality, but this solution is a minimum of 4 lines - so not a lot of work.

I created a model wrapper for my bean, then referenced the related bean in the open() method. open() gets called automatically when R::load() gets called for the related table. So for the OP's situation, the model would look like:

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

Simply referencing ownCompany triggers the lazy loading, which now allows Twig to access the property.

Upvotes: 1

Cerad
Cerad

Reputation: 48865

This shows the basic problem:

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";
    }
}

What is happening is that company is lazy loaded when you do $person->company. Twig checks for the existence of the company property before attempting to load it and does not find it. If you uncomment the $person->company line then the test passes and all will be well.

I didn't see anything in RedBeans to allow eager loading. You could have your controller run through and just call $person->company on each person. Or you could try messing with Twig_Template::getAttribute(); Or maybe even use the queries and work with arrays.

Upvotes: 4

Related Questions