我有一个模型Foo
,其中有许多Bar
:
class Foo extends Model
{
public function bars()
{
return $this->hasMany('App\Bar');
}
}
class Bar extends Model
{
public function foo()
{
return $this->belongsTo('App\Foo');
}
}
保存新的Foo
时,请求有效负载带有Bar
id数组。我想同时保存这些。这有效:
public function store(StoreFoo $request)
{
$foo = Foo::create($request->validated());
foreach ($request->barIds as $barId) {
$foo->bars()->create(['bar_id' => $barId]);
}
}
我的问题是:有没有办法做到这一点而没有循环?我已经尝试过sync
和attach
,但在这种情况下不适用。
答案 0 :(得分:0)
我能想到的唯一无需编写循环即可实现此目标的方法是在saveMany
关系上使用HasMany
方法。您可以创建Bar
模型的实例,并将所有实例作为数组传递给saveMany
方法,这将保存所有实例并作为响应返回创建的实体的数组。
$foo->bars()->saveMany([new Bar(['id' => 1]), new Bar(['id' => 2])]);
话虽这么说,Laravel使用循环在引擎盖下一个个地保存这些模型,所以它与您现在所做的并没有太大不同。
类似地,还有一种createMany
方法,可以与saveMany
相同的方式使用,但是除了提供新创建的模型外,还可以提供属性数组。
答案 1 :(得分:0)
迁移表样本
Schema::create('logs', function(Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id')->default(0)->index();
$table->string('type', 10)->index(); // add, update, delete
$table->string('table', 50)->index();
$table->unsignedBigInteger('row');
$table->dateTime('created_at');
});
Schema::create('log_fields', function(Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('log_id')->index();
$table->string('field', 50)->index();
$table->longText('old');
$table->longText('new');
});
模型Log.php文件
class Log extends Model
{
const UPDATED_AT = null;
protected $fillable = [
'user_id',
'type',
'table',
'row'
];
public function logFields()
{
return $this->hasMany(LogField::class);
}
}
模型LogField.php文件
class LogField extends Model
{
public $timestamps = false;
protected $fillable = [
'field',
'old',
'new'
];
public function log()
{
return $this->belongsTo(Log::class);
}
}
用于另一个模型的引导功能,用于将更改保存在数据库中。 创建,更新和删除挂钩以回答您的问题
public static function boot()
{
parent::boot();
static::created(function($resorce) {
$_log = new Log;
$_log->create([
'user_id' => session('uid', 0),
'type' => 'add',
'table' => $resorce->getTable(),
'row' => $resorce->fresh()->toArray()['id']
]);
return true;
});
static::updating(function($resorce) {
$_log = new Log;
$log = $_log->create([
'user_id' => session('uid', 0),
'type' => 'update',
'table' => $resorce->getTable(),
'row' => $resorce->fresh()->toArray()['id']
]);
foreach($resorce->getDirty() as $field => $new) {
$log->logFields()->create([
'field' => $field,
'old' => $resorce->fresh()->toArray()[$field],
'new' => $new
]);
}
return true;
});
static::deleting(function($resorce) {
$_log = new Log;
$log = $_log->create([
'user_id' => session('uid', 0),
'type' => 'delete',
'table' => $resorce->getTable(),
'row' => $resorce->id,
]);
foreach($resorce->fresh()->toArray() as $field => $value) {
$log->logFields()->create([
'field' => $field,
'old' => '',
'new' => $value
]);
}
return true;
});
}
希望我帮助您了解了这一点。