简体   繁体   English

Laravel 如何使用数据透视表处理一对多关系

[英]Laravel How to handle One To Many relationship using Pivot Tables

I have a new Laravel application that I'm hooking up to a preexisting database.我有一个新的 Laravel 应用程序,我正在连接到一个预先存在的数据库。 The relationships in this database are pretty much all pivot tables.这个数据库中的关系几乎都是数据透视表。

Similar to this:与此类似:

Schema::create('customers', function (Blueprint $table) {
    $table->id();
    $table->string('name');
});

Schema::create('vehicles', function (Blueprint $table) {
    $table->id();
    $table->string('name');
});

Schema::create('customer_vehicle', function (Blueprint $table) {
    $table->id();    
    $table->int('customer_id');
    $table->int('vehicle_id');
});

I've configured models/pivot tables and set up a Many To Many relationship for the customers and vehicles.我已经配置了模型/数据透视表并为客户和车辆建立了多对多关系。

Similar to this:与此类似:

class Customer extends Model
{
    public function vehicles()
    {
        return $this->belongsToMany(
            Vehicle::class,
            CustomerVehiclePivot::class,
            'customer_id',
            'vehicle_id'
        );
    }
}
class Vehicle extends Model
{
    public function customers()
    {
        return $this->belongsToMany(
            Customer::class,
            CustomerVehiclePivot::class,
            'vehicle_id',
            'customer_id'
        );
    }
}

So far this is working, but it doesn't feel quite right.到目前为止,这是可行的,但感觉不太对劲。 $customer->vehicles() returns the expected results, but a vehicle should only belong to one customer, and the way I'm doing that at the moment is by doing $vehicle->customers()->first() . $customer->vehicles()返回预期结果,但车辆应该只属于一个客户,我现在这样做的方式是$vehicle->customers()->first()

The actual relationship should be a One To Many.实际关系应该是一对多。 A customer can have many vehicles, but a vehicle should only belong to one customer.一个客户可以拥有多辆车,但一辆车应该只属于一个客户。

Is there a way to configure the relationship as a One To Many when using a pivot table in order to be able to fetch a vehicle's customer with $vehicle->customer ?有没有办法在使用数据透视表时将关系配置为一对多关系,以便能够使用$vehicle->customer获取车辆的客户?


Based on @chuck's suggestion, I now have the following for my Vehicle customer method.根据@chuck 的建议,我的 Vehicle 客户方法现在有以下内容。

class Vehicle extends Model
{
    public function customer()
    {
        return $this->hasOneThrough(
            Customer::class,
            CustomerVehiclePivot::class,
            'vehicle_id',
            'id',
            'id',
            'customer_id'
        );
    }
}

I can now perform the following and get the expected results.我现在可以执行以下操作并获得预期的结果。

$vehicle->customer; // Returns the vehicle's customer
$customer->vehicles; // Returns the customer's vehicles

I'm now trying to figure out how to use factories with this configuration.我现在正试图弄清楚如何使用具有这种配置的工厂。

I thought I could do Vehicle::factory()->for(Customer::factory())->create() but I get the error...我以为我可以做Vehicle::factory()->for(Customer::factory())->create()但我收到错误...

Call to undefined method Illuminate\Database\Eloquent\Relations\HasOneThrough::getOwnerKeyName()调用未定义的方法 Illuminate\Database\Eloquent\Relations\HasOneThrough::getOwnerKeyName()

So I'm not quite sure how you can create Vehicles for users.所以我不太确定如何为用户创建车辆。

I was successfully able to create users with attached vehicles by using hasAttached .通过使用hasAttached ,我成功地创建了带有附加车辆的用户。

Customer::factory()
    ->hasAttached(
        Vehicle::factory()->count(3)
    )
    ->create()

I was able to figure out how to use factories to create vehicles for users.我能够弄清楚如何使用工厂为用户制造车辆。

Customer::factory()->create()->vehicles()->attach(Vehicle::factory()->count(3)->create());

Yes, you can use the hasOneThrough() relationship in Laravel to set up a one-to-many relationship between customers and vehicles using a pivot table.是的,您可以使用 Laravel 中的 hasOneThrough() 关系,使用数据透视表在客户和车辆之间建立一对多关系。 Here is an example of how you can set this up:以下是如何设置的示例:

class Customer extends Model
{
    public function vehicles()
    {
        return $this->hasMany(Vehicle::class);
    }
}

class Vehicle extends Model
{
    public function customer()
    {
        return $this->hasOneThrough(
            Customer::class,
            CustomerVehiclePivot::class,
            'vehicle_id', // Foreign key on the pivot table
            'id', // Local key on the customers table
            'id', // Local key on the vehicles table
            'customer_id' // Foreign key on the pivot table
        );
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM