Reputation: 15666
How do I handle multiple inverse relations pointing to the same active record? For example:
class Bicycle extends ActiveRecord {
public function getFrontWheel() {
return $this
->hasOne(Wheel::class, ['id' => 'front_wheel_id'])
->inverseOf('bicycles');
}
public function getRearWheel() {
return $this
->hasOne(Wheel::class, ['id' => 'rear_wheel_id'])
->inverseOf('bicycles');
}
}
class Wheel extends ActiveRecord {
public function getBicycles() {
return $this
->hasMany(Bicycle::class, ['???' => 'id'])
->inverseOf('??????');
}
}
What can I do here? I critically need the inverse relations.
Upvotes: 1
Views: 367
Reputation: 15666
Here is my own solution. Key points:
class Bicycle extends ActiveRecord {
public function getFrontWheel() {
return $this
->hasOne(Wheel::class, ['id' => 'front_wheel_id'])
->inverseOf('frontWheelBicycles');
}
public function getRearWheel() {
return $this
->hasOne(Wheel::class, ['id' => 'rear_wheel_id'])
->inverseOf('rearWheelBicycles');
}
}
class Wheel extends ActiveRecord {
public function getFrontWheelBicycles() {
return $this
->hasMany(Bicycle::class, ['front_wheel_id' => 'id'])
->inverseOf('frontWheel');
}
public function getRearWheelBicycles() {
return $this
->hasMany(Bicycle::class, ['rear_wheel_id' => 'id'])
->inverseOf('rearWheel');
}
}
Upvotes: 0
Reputation: 122
i would suggest to do the following:
create two new classes:
in new classes you can set easily the relation.
How to instantiate the correct class? There is a method in ActiveRecord instantiate() where you can write your logic which wheel class need to be created.
class Wheel extends ActiveRecord {
...
public static function instantiate ( $row ) {
if($row['type'] === 'RearWheel') {
return new RealWheel();
}
...
}
full code:
class Bicycle extends ActiveRecord
{
public function getFrontWheel()
{
return $this
->hasOne(Wheel::class, ['id' => 'front_wheel_id'])
->inverseOf('bicycles');
}
public function getRearWheel()
{
return $this
->hasOne(Wheel::class, ['id' => 'rear_wheel_id'])
->inverseOf('bicycles');
}
}
abstract class Wheel extends ActiveRecord
{
public static function instantiate($row)
{
if ($row['type'] === 'RearWheel') {
return new RealWheel();
}
if ($row['type'] === 'FrontWheel') {
return new FrontWheel();
}
throw new InvalidConfigException();
}
abstract public function getBicycles();
}
class RealWheel extends Wheel
{
public function getBicycles()
{
return $this
->hasMany(Bicycle::class, ['rear_wheel_id' => 'id'])
->inverseOf('rearWheel');
}
}
class FrontWheel extends Wheel
{
public function getBicycles()
{
return $this
->hasMany(Bicycle::class, ['front_wheel_id' => 'id'])
->inverseOf('frontWheel');
}
}
Upvotes: -1