Laravel中如何通过关联关系创建含多关联的Company模型
实现嵌套数据创建Company及其关联模型
1. 修正模型关联关系
根据你的表结构(Company表的company_info和address是外键,分别指向company_infos和addresses表的主键),模型间的正确关联应为belongsTo而非hasOne:
// Company模型 class Company extends Model { // 允许批量赋值的字段,包含外键字段 protected $fillable = ['company_info', 'address']; public function companyInfo() { // 参数:关联模型类,当前模型的外键字段,关联模型的主键字段 return $this->belongsTo(CompanyInfo::class, 'company_info', 'id'); } public function address() { return $this->belongsTo(Address::class, 'address', 'id'); } }
同时给关联模型添加反向关联(可选,用于后续查询):
// CompanyInfo模型 class CompanyInfo extends Model { protected $fillable = ['company_name', 'owner']; public function company() { return $this->hasOne(Company::class, 'company_info', 'id'); } }
// Address模型 class Address extends Model { protected $fillable = ['country', 'street', 'number']; public function company() { return $this->hasOne(Company::class, 'address', 'id'); } }
2. 配置批量赋值
确保所有涉及的模型都开启了对应字段的批量赋值(如上述代码中的$fillable配置),否则创建模型时会因字段不可填充报错。
3. 控制器处理嵌套数据创建
使用数据库事务保证数据一致性(避免部分模型创建成功、部分失败的异常情况),先创建关联子模型,再创建Company模型:
use App\Models\Company; use App\Models\CompanyInfo; use App\Models\Address; use Illuminate\Support\Facades\DB; use Illuminate\Http\Request; public function store(Request $request) { // 验证前端提交的嵌套数据 $validated = $request->validate([ 'company_info.company_name' => 'required|string|max:255', 'company_info.owner' => 'required|string|max:255', 'address.country' => 'required|string|max:255', 'address.street' => 'required|string|max:255', 'address.number' => 'required|integer', // 若Company表有其他字段,添加对应的验证规则 ]); // 事务包裹所有操作 DB::beginTransaction(); try { // 先创建CompanyInfo和Address子模型 $companyInfo = CompanyInfo::create($validated['company_info']); $address = Address::create($validated['address']); // 创建Company模型并关联子模型ID $company = Company::create([ 'company_info' => $companyInfo->id, 'address' => $address->id, // 若Company有其他字段,从$validated中取值赋值 ]); // 加载关联数据,返回完整信息 $company->load(['companyInfo', 'address']); DB::commit(); return response()->json([ 'message' => '企业创建成功', 'data' => $company ], 201); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'message' => '企业创建失败', 'error' => $e->getMessage() ], 500); } }
4. 封装创建逻辑(可选优化)
如果需要复用创建逻辑,可以在Company模型中封装静态方法:
// Company模型中添加 public static function createWithRelations(array $data) { return DB::transaction(function () use ($data) { $companyInfo = CompanyInfo::create($data['company_info']); $address = Address::create($data['address']); return self::create([ 'company_info' => $companyInfo->id, 'address' => $address->id, ])->load(['companyInfo', 'address']); }); }
控制器中即可简化为:
public function store(Request $request) { $validated = $request->validate([ // 验证规则同上 ]); $company = Company::createWithRelations($validated); return response()->json([ 'message' => '企业创建成功', 'data' => $company ], 201); }
内容的提问来源于stack exchange,提问作者Moemen Hussein
相关产品推荐
相关产品推荐

