我有一个问题,关于在Laravel中将更新相关模型的逻辑放在何处。
我有一个相对日期模型,该模型取决于固定日期(里程碑)或另一个相对日期。我的应用程序中现在有几个包含这样的相对日期的模型。
如果我查询这样的相对日期,则会得到理想的结果。但是现在我不知道保存或更新逻辑的位置/方式。
请求具有以下结构:
array (
'id' => NULL, // Or id if it already exists
'difference' => 71,
'fixed' => NULL, // Date string if a fixed date is selected
'parent' => NULL, // An array of this format if it depends on another relative date
'milestone' => // Dependency on milestone
array (
'id' => 1, // This id is needed as mileston_id in the db afterwards
'name' => 'Test',
'pit' => '2019-11-01',
),
)
现在,我需要一些逻辑来提取所需的数据(在这种情况下为id, difference, milestone_id
)并创建或更新RelativeDate模型并返回ID。然后可以在“父”模型中引用此ID或模型。
我不想在每个模型的控制器中执行此操作,因为会有很多代码重复。据我所知,不可能在另一个控制器中正确注入一个控制器(RelativeDateController)吗? (这是我的第二个主意)
我考虑了一种获取相对日期数组并针对该相对日期进行所有逻辑和模型映射的服务。然后,我可以在具有相对日期的所有模型中注入此服务?
这是正确的方法吗,或者您甚至会建议其他解决方案?
作为补充信息,我在下面添加了迁移和模型定义。
迁移(相对日期)
Schema::create('relative_dates', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('difference')->nullable(); // Difference to parent date in days
$table->integer('milestone_id')->nullable()->unsigned(); // Relation to milestone or null
$table->date('fixed')->nullable(); // Fixed date
$table->bigInteger('parent_id')->nullable()->unsigned(); // Relation to another relative date or null
$table->foreign('milestone_id')->references('id')->on('milestones')->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreign('parent_id')->references('id')->on('relative_dates')->onDelete('CASCADE')->onUpdate('CASCADE');
});
模型(相对日期)
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class RelativeDate extends Model
{
protected $appends = ['relative_date'];
public function getRelativeDateAttribute()
{
if ( $this->fixed !== null ) {
return Carbon::instance($this->fixed);
} else if($this->milestone_id !== null) {
$mpit = Carbon::instance($this->milestone->pit);
return $mpit->addDays($this->difference);
} else if( $this->parent_id !== null ) {
$parent = $this->parent->relative_date;
return $parent->addDays($this->difference);
}
}
public function milestone(){
return $this->belongsTo('App\Milestone', 'milestone_id', 'id');
}
public function parent(){
return $this->belongsTo('App\RelativeDate', 'parent_id', 'id')->with('parent', 'milestone');
}
}
正如Julien Gabriel所建议的,我试图用特质解决它,并且效果很好。为了完成,这是我的解决方案:
<?php
namespace App\Traits;
use App\RelativeDate as RelativeDateModel;
trait RelativeDate
{
public function updateOrCreate($data)
{
if ($data['fixed'] != null) {
$newData = array(
'difference' => null,
'fixed' => $data['fixed'],
'parent_id' => null,
'milestone_id' => null,
);
} elseif ( $data['milestone'] != null ) {
$newData = array(
'difference' => $data['difference'],
'fixed' => null,
'parent_id' => null,
'milestone_id' => $data['milestone']['id'],
);
} elseif ( $data['parent'] != null ) {
$newData = array(
'difference' => $data['difference'],
'fixed' => null,
'parent_id' => $data['parent']['id'],
'milestone_id' => null,
);
} else {
return null;
}
if ( $data['id'] != null ) {
$rd = RelativeDateModel::find($data['id']);
if ( $rd->update($newData) ) {
return $rd->id;
}
} else {
$rd = RelativeDateModel::create($newData);
return $rd->id;
}
}
}