Yii2:同一模型的多个逆关系?

时间:2021-04-28 02:35:00

标签: yii2 yii2-model yii2-active-records

如何处理指向同一个活动记录的多个逆关系? 例如:

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('??????');
    }

}

我可以在这里做什么?我非常需要逆关系。

2 个答案:

答案 0 :(得分:0)

这是我自己的解决方案。 要点:

  • 这一切都归结为正确的命名。
  • 逆关系是bijective!换句话说,每个关系总是必须在另一端有自己独特的镜像关系。
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');
    }

}

答案 1 :(得分:-1)

我建议您执行以下操作:

创建两个新类:

  • class FrontWheel extends Wheel {
  • class RearWheel extends Wheel {

在新课程中,您可以轻松设置关系。

如何实例化正确的类? ActiveRecord instantiate() 中有一个方法,您可以在其中编写需要创建哪个轮类的逻辑。

class Wheel extends ActiveRecord {
...

  public static function instantiate ( $row ) {
      if($row['type'] === 'RearWheel') {
           return new RealWheel();
      }
      ...

  }

完整代码:

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');
    }

}
相关问题