在HasMany雄辩的关系中保存多个ID

时间:2018-07-17 14:29:58

标签: php laravel eloquent relationship

我有一个模型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]);
    }
}

我的问题是:有没有办法做到这一点而没有循环?我已经尝试过syncattach,但在这种情况下不适用。

2 个答案:

答案 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;
        });
    }

希望我帮助您了解了这一点。