Database 如何设计数据库以存储;“违约”;项目
我正在拉威尔开发一个应用程序。我有一个叫Account和ShippingAddress的模型。一个帐户可以有一个或多个ShippingAddress,但ShippingAddress只能有一个帐户。所以我用的是一对多的关系 现在我想实现一个功能,将发货地址标记为“默认”,每个“帐户”只能有一个“默认发货地址”。我已经确定了两种可能的解决方案:Database 如何设计数据库以存储;“违约”;项目,database,laravel,laravel-5,database-design,Database,Laravel,Laravel 5,Database Design,我正在拉威尔开发一个应用程序。我有一个叫Account和ShippingAddress的模型。一个帐户可以有一个或多个ShippingAddress,但ShippingAddress只能有一个帐户。所以我用的是一对多的关系 现在我想实现一个功能,将发货地址标记为“默认”,每个“帐户”只能有一个“默认发货地址”。我已经确定了两种可能的解决方案: 在ShippingAddress表中添加“is_default”列 创建一个“default\u shipping\u address”透视表,我将在其中
你认为哪一个是最好的解决方案?为什么?对于第二个问题:如何通过透视表实现Laravel中的一对一关系?考虑到一个
发货地址只属于一个帐户,使用透视表似乎有点多余,第一个解决方案看起来更干净
顺便说一句,您可以通过以下方式设计模型
:
类帐户扩展模型
{
公共功能发送地址()
{
返回$this->hasMany('App\ShippingAddress');
}
公共函数默认值\发货\地址()
{
返回$this->hasOne('App\ShippingAddress')->where('is_default',true);
}
}
类ShippingAddress扩展模型
{
公共职能账户()
{
返回$this->belongsTo('App\Account');
}
}
这样,当您检索帐户
模型时,您可以“配送地址”
或仅“默认配送地址”
,例如:
$account=account::with('shipping_addresses')->find($id);
$account=account::with('default\u shipping\u address')->find($id);
显然,您不需要将这两个关系都立即加载
,因为发货地址
已经包含了defaut发货地址
您只需使用validation()或database或两者检查代码中是否只有一个默认发货地址。我个人的观点是,对于单个收藏夹地址,使用透视表,尽管从形式上看可能更正确,只会给查询增加复杂性。相反,通过在地址中添加一个标志列来确定它的收藏时间,这将使查询更容易
现在,如果要使用数据透视表,应使用以下函数在帐户模型中建立关系:
public function defaultShippingAddress()
{
return $this->hasOneThrough('App\Models\AccountShippingAddress', 'App\Models\ShippingAddress');
}
在这里,您可以阅读有关它的全部文档
问候 我会选择选项1,因为它更简单,没有缺点。为了确保每个帐户只有一个默认ShippingAddress
,您可以监听saving
事件,并执行如下验证:
class ShippingAddress extends Model
{
// ... other code
public function boot()
{
parent::boot();
static::saving(function (ShippingAddress $shippingAddress) {
if (! $shippingAddress->is_default) {
return;
}
$defaultAlreadyExists = static::where([
['account_id', '=', $shippingAddress->account_id],
['id', '!=', $shippingAddress->id],
['is_default', '=', true],
])->exists();
if ($defaultAlreadyExists) {
throw new YourCustomException("Account with id {$shippingAddress->account_id} already has a default shipping address");
}
});
}
// ... other code
}
我想探索这个答案,但我不太明白。我将按如下方式设计我的数据库:帐户[id,…]
,发货地址[id,帐户id,…]
,默认发货地址[account\u id,发货地址\u id]
。现在,我创建了一个DefaultShippingAddress
,它扩展了illumb\Database\Eloquent\Relations\Pivot
,因为阅读文档听起来是正确的做法。然后我通过反转参数来实现您建议的方法。但是如果我尝试执行该方法,它将返回一个QueryException
:它无法检索shipping\u addresses.id
。我做错了什么?让我试着实现你的模型,我会回来给出更好的解释。