【问题标题】:Laravel eloquent calculate work experienceLaravel 雄辩的计算工作经验
【发布时间】:2018-11-10 09:09:02
【问题描述】:

我有用户工作经验的自定义表格:

Schema::create('workplaces', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('user_id');
    $table->foreign('user_id')
          ->references('id')
          ->on('users')
          ->onDelete('cascade');
    $table->string('company')->nullable();
    $table->string('position')->nullable();
    $table->string('description')->nullable();
    $table->smallInteger('from')->nullable();
    $table->smallInteger('to')->nullable();
    $table->timestamps();
});

这里是用户体验数据示例:

----------------------------------------------------------
| user_id | company | position | description | from | to |
----------------------------------------------------------
----------------------------------------------------------
|    1    | Google  | Designer | Lorem ipsum | 2018 |null|
----------------------------------------------------------
----------------------------------------------------------
|    1    |  Yahoo  | Designer | Lorem ipsum | 2014 |2017|
----------------------------------------------------------
----------------------------------------------------------
|    1    |Microsoft| Designer | Lorem ipsum | 2004 |2008|
----------------------------------------------------------

在此示例中,id == 1 的用户拥有 7 年 工作经验。

2018 - (2017 - 2014) - (2008 - 2004) = 2011

用户去年在 2018 年工作,现在我需要从上一个工作年减去结果:

2018 - 2011 = 7

现在,当前用户有 7 年的工作经验。

如何使用 laravel eloquent 计算自定义工作经验?

【问题讨论】:

  • 你想输出什么?你能解释一下吗?
  • @HamidNaghipour 我需要计算用户工作经验。在我的示例中,数据用户有 7 年的工作经验。我如何用 eloquent 计算它?

标签: laravel eloquent laravel-5.7


【解决方案1】:

1) 在app 文件夹中创建一个模型,文件名为Workplace.php,内容如下:

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Workplace extends Model 
{
    protected $table = 'workplaces';

    protected $fillable = ['user_id', 'company', 'position', 'description', 'from', 'to'];

    public $timestamps = true;


    public function user()
    {
        return $this->belongsTo('App\User');
    }

    public function experienceYears() 
    {
      $from = property_exists($this, 'from') ? $this->from : null;
      $to = property_exists($this, 'to') ? $this->to : null;
      if (is_null($from)) return 0;
      if (is_null($to)) $to = $from; // or = date('Y'); depending business logic
      return (int)$to - (int)$from;
    }

    public static function calcExperienceYearsForUser(User $user) 
    {
        $workplaces = 
            self::with('experienceYears')
                  ->whereUserId($user->id)
                  ->get(['from', 'to']);
        $years = 0;
        foreach ($workplaces AS $workplace) {
          $years+= $workplace->experienceYears;
        }
        return $years;
    }
}

2) 在控制器的操作中使用它:

$userId = 1;
$User = User::findOrFail($userId);
$yearsOfExperience = Workplace::calcExperienceYearsForUser($User);

【讨论】:

  • 你认为我怎样才能让用户获得更多或更少 n - 年经验的用户?
  • @AndreasHunter 对于这种情况您必须将experience_years 字段添加到users 表并制作将定期运行的控制台命令并进行计算和更新该字段。
【解决方案2】:

我相信您应该在数据库端进行此类计算。这将是一个更快、更灵活的解决方案。如果您有 100 万个拥有多个体验条目的用户,并且想要选择前 10 名最有经验的用户怎么办?在 PHP 端做这样的计算会非常低效。

这是一个可能完成主要工作的原始查询 (Postgres):

SELECT SUM(COALESCE(to_year, extract(year from current_date)) - from_year) from experiences;

如果你想玩弄它并测试其他情况:http://sqlfiddle.com/#!9/c9840b/3

其他人可能会说这是一个过早的优化,但它是单行的。原始查询功能非常强大,应该更频繁地使用。

【讨论】:

  • 这是完美的解决方案,但问题是:如何使用 laravel eloquent 计算自定义工作经验?我希望没有这样的要求来显示前 10 个用户(:这将导致将 experience_years 添加到 users 表和后台工作人员或数据库触发器,它将计算数字并更新该字段
  • 好吧,我只是想提供一个想法。人们总是可以在 Model 类中“隐藏”原始查询位,以使其更有说服力。由于您的回答在技术上是正确的,我认为没有必要详细说明替代方案。我同意汇总表/触发器部分。
  • 对你的答案做额外的补充怎么样?因为安德烈亚斯现在想要这个功能(:
猜你喜欢
  • 2012-10-23
  • 2016-06-01
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多