首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用计算值的Laravel作用域

问使用计算值的Laravel作用域
EN

Stack Overflow用户
提问于 2018-09-29 01:25:22
回答 4查看 716关注 0票数 0

我在Laravel 5.4中遇到了以下问题:有一个用户表和一个成员资格表,其中一个用户可以有多个成员资格,一个成员资格属于一个用户。会员资格是每年一次的,但会员推荐在我的网站上注册的每个朋友都将获得额外的免费天数,因此免费天数不断变化;这反过来又改变了会员的到期日期。因此,问题是:如果过期日期是一个变量,如何确定给定用户的活动成员资格的范围?我需要这样做:

首先是Membership.php中的到期日期:

这将计算每个成员的总天数:请注意,在User.php中计算每个用户的friendsDays

代码语言:javascript
复制
public function getTotalDaysAttribute() {
        $days = $this->paidDays + $this->user->friendsDaysRemaining;
        return $days;
    }

这将计算每个成员的过期日期:

代码语言:javascript
复制
public function getExpirationDateAttribute() {
    $date = $this->startDay->addDays($this->TotalDays);
    return $date;
}

到目前为止一切顺利..。现在,这就是我被卡住的地方(伪代码):

代码语言:javascript
复制
public function scopeActive($query, $dateToCheck = Null) {
   $query->where($dateToCheck >= $this->expirationDate);
}

如何对其进行正确编码以获取:

代码语言:javascript
复制
dump($user->membership()->active()->get());

提前谢谢。

EN

回答 4

Stack Overflow用户

发布于 2018-09-29 01:40:43

您有两个问题:

  1. 您正尝试在您的作用域中使用模型值。作用域在设置模型值之前发生。这是因为,由于数据库设计的原因,为了获得要设置的模型中的值,获取数据的查询必须首先是executed.
  2. Unfortunately,您将无法创建一个作用域来获得所需的答案。这是因为您正在使用不同表中的值来计算TotalDays值。

我建议您更改数据库中的expirationDate值,并在邀请朋友时调用它。

类似于:

代码语言:javascript
复制
function addDaysToExpiration(User $user) {
    $user->expirationDate = date('Y-m-d h:m:s', strtotime('2008-10-05' . '+1 day'));
    $user->save();
}
票数 1
EN

Stack Overflow用户

发布于 2018-09-29 02:00:41

您可以将变量传递给作用域,例如,您可以这样定义作用域:

代码语言:javascript
复制
public function scopeActive($query, \Carbon\Carbon $dateToCheck = Null) 
{
   $query->where('some_date_field',  '>=' ($expirationDate ?? now())->toDateTimeString());
}

然后你可以这样做:

代码语言:javascript
复制
$dateToCheck = now()->addDays(30);

dump($user->membership()->active($dateToCheck)->get());

如果在您的情况下使用更方便的话,您还可以只将天数传递给scope而不是Carbon实例。

票数 0
EN

Stack Overflow用户

发布于 2018-09-29 02:17:06

使用您为自己定义的API:

代码语言:javascript
复制
$user->membership()->active()->get();

您的方法scopeActive将无法看到计算到期日期所需的相关User和friendsDaysRemaining变量。你可以自己尝试一下:

代码语言:javascript
复制
public function scopeActive($query) {
   var_dump($this->id); // null
   var_dump($this->user); // null, this part will try to do the query: select * from users where id = null
}

在您的位置上,我可能会在memberships表上使用一个持久化的expiration_date列,并在需要时更新它。这将允许您执行smth,如下所示:

代码语言:javascript
复制
public function scopeActive($query) {
    return $query->where('expiration_date', '>', Carbon::now());
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52560139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档