我创建了一个自定义的push()方法,该方法以级联方式保存所有模型的关系,并收集实体和子级详细信息的完整快照以供审计日志使用。
所有事物都与belongsTo配合良好,并且有许多关系。我只做如下:
$ae->target()->associate(new AuditableEntryTarget(["name" => "single target"]));
$ae->children->add(new AuditableEntryChild(["name" => "one of children"]));
$ae->children->add(new AuditableEntryChild(["name" => "two of children"]));
// add grandchildren to the first child
$ae->children[0]->children->add(new AuditableEntrySubChild(["name" => "one of subchildren for first child"]));
// add target subchild
$ae->target->subtarget()->associate(new AuditableEntryTargetChild(["name" => "single target child"]));
// my custom method which saves and collects to audit log all the children, no matter if they are attached through hasMany or belongsTo
$ae->push();
但问题出在hasOne关系上。它不提供任何方法在不先保存的情况下将相关模型附加到我的根模型。HasOne关系在Laravel:中只有save()方法
/**
* Attach a model instance to the parent model.
*
* @param 'Illuminate'Database'Eloquent'Model $model
* @return 'Illuminate'Database'Eloquent'Model
*/
public function save(Model $model)
{
$model->setAttribute($this->getPlainForeignKey(), $this->getParentKey());
return $model->save() ? $model : false;
}
正如您所看到的,它不仅关联,而且保存了模型。为了能够检测字段的所有更改,我的方法要求将关系附加到模型,但尚未保存,因为否则我将无法拦截保存过程并将数据附加到快照。BelongsTo
有associate
,hasMany
有add
,用于在不保存模型的情况下附加模型,但我找不到类似的hasOne。
是否有任何方法可以将新的模型实例附加到hasOne关系而不立即保存(类似于belongsTo
的associate
或hasMany
的add
)
在Laracasts的帮助下,解决方法似乎是
$model->setRelation('child', $childInstance);
不过,奇怪的是,Laravel并没有像初始化hasMany那样初始化hasOne关系。