You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:05:12