Laravel工厂能否为多对多关联表position字段设置递增值?
Laravel工厂给多对多关联的position字段递增值的解决办法
完全可以实现,别用官方文档里那种直接给所有关联记录设同一个position的写法,要给每个Product单独绑定对应的位置值,下面两种方法都能用:
方法一:用集合map生成带position的关联数组
在Listing工厂里加个状态方法,先创建一批Product,再遍历它们生成带position的数组,最后批量关联:
use App\Models\Listing; use App\Models\Product; use Illuminate\Database\Eloquent\Factories\Factory; class ListingFactory extends Factory { protected $model = Listing::class; public function definition() { return [ 'name' => $this->faker->company(), // 其他Listing字段 ]; } // 自定义状态:给Listing关联指定数量的Product,自动设置position public function withProducts($count = 3) { return $this->afterCreating(function (Listing $listing) use ($count) { // 先创建count个Product $products = Product::factory()->count($count)->create(); // 遍历Product,给每个加上position(索引从0开始,所以+1得到1、2、3...) $attachedData = $products->map(function ($product, $index) { return [ 'id' => $product->id, 'position' => $index + 1 ]; })->toArray(); // 批量关联,每个Product对应自己的position $listing->products()->attach($attachedData); }); } }
用的时候直接调用这个状态:
// 给每个Listing关联5个Product,position从1到5 Listing::factory()->withProducts(5)->create();
方法二:循环逐个关联设置position
如果不想写状态方法,也可以在工厂的configure方法里循环处理,更直观:
public function definition() { return [ 'name' => $this->faker->company(), ]; } public function configure() { return $this->afterCreating(function (Listing $listing) { $productCount = 3; // 默认关联3个Product $products = Product::factory()->count($productCount)->create(); // 逐个关联,每次设置对应的position foreach ($products as $index => $product) { $listing->products()->attach($product, ['position' => $index + 1]); } }); }
为啥之前的写法不行?
你之前用的hasAttached(Product::factory()->count(3), ['position' => 1]),这种写法是给所有关联的Product都绑定同一个position值,所以全是1。必须要给每个Product单独指定position,不管是用map生成带属性的数组,还是循环逐个attach,都能实现递增的效果。
内容的提问来源于stack exchange,提问作者billyonecan
相关产品推荐
相关产品推荐

