Reputation: 2582
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?
Upvotes: 2
Views: 485
Reputation: 2582
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')));
Upvotes: 2