【问题标题】:Laravel (eloquent) accessors: Calculate only onceLaravel(雄辩)访问器:只计算一次
【发布时间】:2016-06-01 03:49:34
【问题描述】:

我有一个 Laravel 模型,它有一个计算的访问器:

Model Job 有一些 JobApplicationsUser 相关联。 我想知道用户是否已经申请了工作。

为此,我创建了一个访问器user_applied,它获取与当前用户的applications 关系。这可以正常工作,但是每次我访问该字段时都会计算访问器(进行查询)。

是否有任何简单的方法可以只计算访问器一次

/**
 * Whether the user applied for this job or not.
 *
 * @return bool
 */
public function getUserAppliedAttribute()
{
    if (!Auth::check()) {
        return false;
    }

    return $this->applications()->where('user_id', Auth::user()->id)->exists();
}

提前致谢。

【问题讨论】:

    标签: php laravel optimization eloquent accessor


    【解决方案1】:

    我会在你的 User 模型上创建一个方法,你将 Job 传递给它,并返回一个关于用户是否已应用的布尔值:

    class User extends Authenticatable
    {
        public function jobApplications()
        {
            return $this->belongsToMany(JobApplication::class);
        }
    
        public function hasAppliedFor(Job $job)
        {
            return $this->jobApplications->contains('job_id', $job->getKey());
        }
    }
    

    用法:

    $applied = User::hasAppliedFor($job);
    

    【讨论】:

    • 干杯。这个很酷的转变肯定会解决这个问题。但是,如果有一种方法可以只计算一次访问器,那就太好了……
    • 您可以在模型上设置属性。然后在后续调用中,检查属性是否有值,如果有,则使用它,如果没有,则执行计算。
    • 是的,这可以解决问题...非常棘手,但可以。谢谢!
    • 没问题。很高兴能帮上忙!
    【解决方案2】:

    正如评论中所建议的那样,真的一点也不棘手

     protected $userApplied=false;
    /**
     * Whether the user applied for this job or not.
     *
     * @return bool
     */
     public function getUserAppliedAttribute()
    {
        if (!Auth::check()) {
            return false;
        }
    
        if($this->userApplied){
            return $this->userApplied;
        }else{
            $this->userApplied = $this->applications()->where('user_id', Auth::user()->id)->exists();
    
            return $this->userApplied;
        } 
    

    }

    【讨论】:

      【解决方案3】:

      您可以将user_applied 值设置为model->attributes 数组,并在下次访问时从属性数组中返回。

      public function getUserAppliedAttribute()
      {
          $user_applied =  array_get($this->attributes, 'user_applied') ?: !Auth::check() && $this->applications()->where('user_id', Auth::user()->id)->exists();
          array_set($this->attributes, 'user_applied', $user_applied);
          return $user_applied;
      }
      

      array_get 第一次访问时将返回null,这将导致?: 的下一个边被执行。 array_set 将评估值设置为 'user_applied' 键。在随后的调用中,array_get 将返回之前设置的值。

      这种方法的额外优势是,如果您在代码中的某处设置了user_applied(例如Auth::user()->user_applied = true),它会反映这一点,这意味着它将返回该值而无需执行任何额外的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-23
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 1970-01-01
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多