简体   繁体   中英

How to get an attribute value as Model instance in PHP ActiveRecord?

I am trying to achieve something that should be simple but seems impossible in PHP ActiveRecord.

In the simplified example I created, I have two models, Person and Exchange, and two tables, people(id, name) and exchange(id, user_from_id, user_to_id, comment) . exchange.user_from_id and exchange.user_to_id have a foreign key constraint referencing people.id .

So when I run the following code:

$exchange = Exchange::first();
echo $exchange->user_from_id;
echo $exchange->user_from_id->name;

I would expect the first echo to fail and the second one to succeed. Instead, the first one succeeds and prints the litteral value of exchange.user_from_id and then obviously the second one generates a "Trying to get property of non-object" warning.

The result is the same with or without adding the following to Exchange:

static $belongs_to = array(
    array('user_from_id', 'class_name' => 'Person'),
    array('user_to_id', 'class_name' => 'Person')
);

What should I change in my code to make it so that $exchange->user_from_id returns an instance of the Person class?

It turns out I had misunderstood how BelongsTo work. I thought it somehow bound a property of a Model, corresponding to an attribute, to a different Model, but I realise now it creates a new property, which you then have to explicitely associate with an attribute using the foreign_key option.

Concretely, this is what I had to add to the Exchange:

static $belongs_to = array(
    array('user_from',
          'class_name' => 'Person',
          'foreign_key' => 'user_from_id'),
    array('user_to',
          'class_name' => 'Person',
          'foreign_key' => 'user_to_id')
);

Then, using this code:

$exchange = Exchange::first();
echo $exchange->user_from;
echo $exchange->user_from->name;

I finally got what I expected: a fatal error on the first echo and the second one printing people.name where people.id = exchange.user_from_id .

This also made it possible to use eager loading of the two people objects with:

$exchange = Exchange::first(array('include' => array('user_from', 'user_to')));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM