如何在Laravel中建立双向关系

时间:2017-12-04 08:53:42

标签: php laravel

有没有办法设置2个模型之间的关系,所以加载hasMany关系时,belongsTo关系会自动设置为调用者/父级?

当在产品上使用保存触发器时,我们会遇到内存问题,该保存触发器会在订单的新副本中加载,并附带每个产品的新副本。 因此,如果一个订单有100个产品,并试图循环使用order-> products-> order->产品,它会加载101个订单,共计10100个产品。

解决这个问题的一种方法是使用setRelation()在控制器的循环中设置belongsTo关系。

我更喜欢是否有办法从模型中设置该关系。

<?php
class Order extends Model {
    public function products() {
        return $this->hasMany(Product::class);
    }

    public function updateTotals() {
        foreach ($this->products as $product) {
            // code
        }
        $this->save();
    }
}

class Product extends Model {
    public function order() {
        return $this->belongsTo(Order::class);
    }

    public static function boot() {
        parent::boot();
        static::updated(function (Product $product) {
            $product->order->updateTotals();
        });
    }
}

class OrderController extends Controller {
    public function postView(UserOrderSaveRequest $request) {
        $order = $request->getOrder();
        foreach ($order->products as $product) {
            $product->setRelation('order', $order);
            // code
            $product->save();
        }
    }
}

更新1: 测试我用来测试答案

// tinker function to fetch the first order
$o = Order();

// load 2 products
$o->products[0];
$o->products[1];

// Set relation
$o->products[0]->setRelation('order', $o);
$o->products[1]->setRelation('order', $o);

// load 2 products orders
$o->products[0]->order;
$o->products[1]->order;

// Test 1 (true if setRelation was used)
// (false in @Bilal Maqsood answer)
$o === $o->products[0]->order;

// Test 2 (true if setRelation was used)
// (true in @Bilal Maqsood answer)
$o->products[1]->order === $o->products[0]->order;

// Test 3 (false?)
$o->products[1]->order->products[0] === $o->products[0]->order->prodcuts[0]

1 个答案:

答案 0 :(得分:1)

更新您的产品型号代码,如

class Product extends Model {

    protected $with = ['order'];

  public function order() {
        return $this->belongsTo(Order::class);
  }

}

$with属性为每个产品记录加载定义的关系。