Laraveleloquent计算工作经验
Laravel eloquent calculate work experience
我有自定义 table 用户工作经验:
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 计算自定义工作经验?
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);
我相信你应该在数据库端做这样的计算。这将是一个更快、更灵活的解决方案。如果您有 100 万具有多个体验条目的用户并且想要 select 排名前 10 位最有经验的用户怎么办?在PHP端做这样的计算效率会非常低。
这是一个原始查询 (Postgres),可能会完成该工作的主要部分:
SELECT SUM(COALESCE(to_year, extract(year from current_date)) - from_year) from experiences;
如果您想试用它并测试其他情况:http://sqlfiddle.com/#!9/c9840b/3
其他人可能会说这是一个过早的优化,但它是一个单行。原始查询功能非常强大,应该经常使用。
我有自定义 table 用户工作经验:
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 计算自定义工作经验?
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);
我相信你应该在数据库端做这样的计算。这将是一个更快、更灵活的解决方案。如果您有 100 万具有多个体验条目的用户并且想要 select 排名前 10 位最有经验的用户怎么办?在PHP端做这样的计算效率会非常低。
这是一个原始查询 (Postgres),可能会完成该工作的主要部分:
SELECT SUM(COALESCE(to_year, extract(year from current_date)) - from_year) from experiences;
如果您想试用它并测试其他情况:http://sqlfiddle.com/#!9/c9840b/3
其他人可能会说这是一个过早的优化,但它是一个单行。原始查询功能非常强大,应该经常使用。