问题描述
我是 Laravel 的新手(使用 v7),所以如果我做错了,我深表歉意。 我为我的用户定制了订阅设置。
id | 名字 | 姓氏 |
---|---|---|
1 | 约翰 | 能源部 |
2 | 简 | 能源部 |
id | 姓名 |
---|---|
1 | 基础 |
2 | 青铜 |
3 | 银色 |
4 | 黄金 |
5 | 白金 |
还有一个 subscription_user 数据透视表
id | user_id | subscription_id | created_at | expired_at |
---|---|---|---|---|
1 | 1 | 1 | 2021-02-01 23:22:12 | 2021-03-21 08:22:12 |
2 | 1 | 5 | 2021-03-21 08:22:12 | 2021-04-04 09:03:21 |
2 | 1 | 3 | 2021-04-04 09:03:21 | |
2 | 2 | 1 | 2021-01-01 01:00:00 | 2021-01-05 05:30:00 |
2 | 2 | 2 | 2021-01-05 05:30:00 | 2021-01-06 08:34:10 |
因此,根据上述条目,John Doe
订阅了基本订阅,然后升级到白金,最后降级到白银。这是他目前的订阅。
我有以下方法(在 User.PHP 中)首先获取用户订阅列表
public function subscriptions()
{
return $this->belongsToMany('App\Subscription')
->orderby('pivot_created_at','desc')
->withPivot('created_at','expired_at')
->withTimestamps();
}
public function subscription()
{
return $this->subscriptions->first();
}
但是,在某些情况下,用户的所有订阅都已过期,因此他们没有当前订阅。即在上述记录中 Jane Doe
谁订阅了 2 个计划,但都已过期。
如果我在 Jane Doe 上调用 $user->subscription()
,它仍然返回最新的过期条目。
我曾尝试将 where()
子句添加到我的 subscription
方法中,但没有效果:
public function subscription()
{
return $this->subscriptions->where('expired_at',NULL)->first();
}
有没有更好的方法来完成我想要实现的目标?我需要一种方法来获取所有用户订阅,无论它们是活动的还是过期的。 (我有 - 这是最好的方法吗?)
但随后也获取不应始终包含 expired_at
的当前订阅。
看来我无法在 mt subscription
方法中添加任何进一步的条件。
解决方法
您需要为订阅方法使用查询构建器,使用 subscriptions()
而不是集合 subscriptions
public function subscription()
{
return $this->subscriptions()->whereNull('expired_at')->first();
}
调用 $this->subscriptions
等同于 $this->subscriptions = $this->subscriptions()->get()
。其中 $this->subscriptions
返回一个集合。
$this->subscriptions()
,使用该方法,返回一个查询构建器。
PS:它没有触发调用 first()
的错误,因为 Collection 也有一个名为 first()
的方法。