如何在Laravel中为belongsTo关联赋值且不保存到数据库?
模型代码
Product 模型
<?php namespace App\Models; class Product extends Model { // 模型其他属性 public function productType() { return $this->belongsTo( 'App\Models\ProductType', 'product_type_id'); } public function theComplicatedFunctionBeingTested() { // 结合 ProductType 的计算逻辑 return $result; } }
ProductType 模型
<?php namespace App\Models; class ProductType extends Model { // 模型其他属性 public function products() { return $this->hasMany( 'App\Models\Product', 'product_id'); } }
测试代码(原尝试)
<?php use Illuminate\Foundation\Testing\TestCase; use App\Models\Product; use App\Models\ProductType; class ProductFunctionTest extends TestCase { private $testProduct, $testProductType; private function commonDataSetUp() { $this->testProductType = new ProductType; $this->testProductType->product_type_id = 1; $this->testProductType->name = "publication"; $this->testProduct = new Product; $this->testProduct->name = "testing product"; // 直接赋值关联无效 $this->testProduct->productType = $this->testProductType; } public function testComplicatedProductFunction() { $this->commonDataSetUp(); $result = $this->testProduct->theComplicatedFunctionBeingTested(); $this->assertEquals( 'my_expected_result', $result); } }
无数据库环境下设置关联的解决方法
直接赋值productType属性无效,因为Laravel的关联动态属性默认会触发数据库查询。可以用以下两种方式跳过数据库操作,手动设置关联:
方法一:使用setRelation方法
Laravel模型内置的setRelation方法可以直接将关联对象存入模型的已加载关联集合,访问时不会触发查询:
private function commonDataSetUp() { $this->testProductType = new ProductType; $this->testProductType->product_type_id = 1; $this->testProductType->name = "publication"; $this->testProduct = new Product; $this->testProduct->name = "testing product"; // 直接设置已加载的关联 $this->testProduct->setRelation('productType', $this->testProductType); }
方法二:用associate方法关联
手动设置外键后,通过关联方法的associate绑定模型,同样不会触发数据库操作:
private function commonDataSetUp() { $this->testProductType = new ProductType; $this->testProductType->product_type_id = 1; $this->testProductType->name = "publication"; $this->testProduct = new Product; $this->testProduct->name = "testing product"; // 设置外键值 $this->testProduct->product_type_id = $this->testProductType->product_type_id; // 关联模型 $this->testProduct->productType()->associate($this->testProductType); }
注意事项
- 确保测试的方法中,访问关联时使用动态属性
$this->productType,而非调用关联方法$this->productType()(后者会返回查询构造器,可能触发数据库查询)。 - 如果方法中必须调用
$this->productType(),提前用setRelation加载关联后,调用方法再访问属性也会使用已加载的对象。
内容的提问来源于stack exchange,提问作者cytsunny
相关产品推荐
相关产品推荐

