我是一个尝试使用 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';
}
确保定义表名以避免被继承猜到。然后告诉
VIPCustomer
与 VIPCustomerData
有关系.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/