php - Laravel Eloquent 模型继承

标签 php laravel inheritance model eloquent

我是一个尝试使用 Laravel 5.5 和 Eloquent 模型构建应用程序的新手。

我有两个类(class):(1)
客户
和 (2)
VIP客户它扩展了客户。

您可以立即告诉 VIPCustomer 包含客户拥有的所有属性以及其他额外属性。

需要明确的是,客户可能不是VIP,而VIP必须是客户;客户可以在他第一次购物时立即选择成为 VIP。

因此,我试图在数据库中做这样的事情:

顾客:

+------------------------+
|id|name|gender|join_date|
+------------------------+

VIP客户:
+----------------------------------+
|customer_id|valid_until|type|point|
+----------------------------------+
(customer_id is a foriegn key referencing Customer.id)

因此,在模型 php 文件中:
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{

}

.

namespace App;

use Illuminate\Database\Eloquent\Model;

class VIPCustomer extends Customer
{
    public $incrementing = false;
}

就这样?我看到有人说我应该使用多态关系,但我不明白这是什么意思。

另外,是否可以像这样实例化一个新的VIP客户?
$customer = new VIPCustomer;
$customer->name   = 'Alice';
$customer->gender = 'F';
$customer->type   = 'gold';
$customer->point  =  0;
$customer->save();

最重要的是,比如当 VIP 成员(member)资格结束时,是否可以将该人保留为 客户 ?因为我担心删除那个人会从 Customer 和 VIPCustomer 表中删除他。

非常感谢您提前。

最佳答案

您当前的 VIPCustomer class 看起来像一个包含 VIP 数据的类,而不是一个主题(客户)。那么,我将其重命名为 VIPCustomerData在这里制作一个新的 VIPCustomer继承Customer类代替。

class Customer extends Model
{
    protected $table = 'customers';
}

确保定义表名以避免被继承猜到。然后告诉VIPCustomerVIPCustomerData 有关系.
class VIPCustomer extends Customer
{
    public function vipData()
    {
        return $this->hasOne(VIPCustomerData::class, 'customer_id', 'id');
    }
}

现在,问题是每当您要检索像 VIPCustomer::get() 这样的 VIP 客户时。 ,您将获得整个客户。因此,需要应用全局作用域。
class VIPCustomer extends Customer
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('weareviptypeofcustomer', function ($q) {
            $q->has('vipData'); // only customers with vip data
        });
    }

    public function vipData()
    {
        return $this->hasOne(VIPCustomerData::class, 'customer_id', 'id');
    }
}

要创建一个新的 Customer 作为 VIP,当然需要在此处插入 2 个查询。例子,
$vipCustomer = new VIPCustomer;
$vipCustomer->name   = 'Alice';
$vipCustomer->gender = 'F';
$vipCustomer->save();

$vipCustomerData = new VIPCustomerData;
$vipCustomerData->type   = 'gold';
$vipCustomerData->point  =  0;

$vipCustomer->vipData()->save($vipCustomerData);

更新点示例。
$vipCustomerData = $vipCustomer->vipData; // or $vipCustomer->vipData()->first();
$vipCustomerData->point  =  10;
$vipCustomerData->save();

从客户中删除 VIP 身份的示例。当然,只需从其表中删除 VIPCustomerData。
$vipCustomer->vipData()->delete();

但是,如果没有专门的列来区别对待每个科目,最好将这些科目保持为一个类。
class Customer extends Model
{
    protected $table = 'customers';

    protected $with = ['vipData']; // always eager load related 'vipData'

    protected $appends = ['is_vip']; // append 'is_vip' accessor

    public function vipData()
    {
        return $this->hasOne(static::class, 'customer_id', 'id');
    }

    public function getIsVipAttribute()
    {
        return (bool) $this->vipData;
    }
}

$customers = Customer::all();

foreach($customers as $customer) {
    if ($customer->is_vip) {
        // is VIP
    } else {

    }
}

关于php - Laravel Eloquent 模型继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48127334/

相关文章:

php - 如何使用日期模块在 Drupal 中正确显示时间?

php - Cakephp 创建 secret 输入的最佳方法

mysql - Laravel 具有整数值的多个连接条件

c# - 如何将继承一次应用于一组类

codeigniter - 如何在 CodeIgniter 中从另一个模型继承一个模型

PHP mySQL 错误

java - 在 Android Studio 中将数据从 MySQL 显示到 TextView

php - 根据日期和名称对行求和

php - 无法重定向到 Laravel 5.2 中的路径

python - 可以从嵌套类定义实现继承吗?