Yii2:与同一模型的多个逆关系?
Yii2: Multiple inverse relations to same model?
如何处理指向同一活动记录的多个反向关系?
例如:
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('??????');
}
}
我可以在这里做什么?我非常需要逆关系。
我建议执行以下操作:
创建两个新的 classes:
- class FrontWheel 延伸车轮 {
- class 后轮伸出车轮 {
在新的 classes 中,您可以轻松设置关系。
如何实例化正确class? ActiveRecord instantiate() 中有一个方法,您可以在其中编写需要创建轮 class 的逻辑。
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');
}
}
这是我自己的解决方案。
要点:
- 这一切都归结为正确的命名。
- 逆关系是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');
}
}
如何处理指向同一活动记录的多个反向关系? 例如:
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('??????');
}
}
我可以在这里做什么?我非常需要逆关系。
我建议执行以下操作:
创建两个新的 classes:
- class FrontWheel 延伸车轮 {
- class 后轮伸出车轮 {
在新的 classes 中,您可以轻松设置关系。
如何实例化正确class? ActiveRecord instantiate() 中有一个方法,您可以在其中编写需要创建轮 class 的逻辑。
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');
}
}
这是我自己的解决方案。 要点:
- 这一切都归结为正确的命名。
- 逆关系是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');
}
}