代码之家  ›  专栏  ›  技术社区  ›  GluePear

在一个有很多说服力的关系中保存多个ID

  •  1
  • GluePear  · 技术社区  · 6 年前

    我有一个模特 Foo ,它有很多 Bar s:

    class Foo extends Model
    {
        public function bars()
        {
            return $this->hasMany('App\Bar');
        }
    }
    
    class Bar extends Model
    {
        public function foo()
        {
            return $this->belongsTo('App\Foo');
        }
    }
    

    当保存一个新的 ,请求有效负载带有一系列 酒吧 身份证。我想同时保存这些。这是有效的:

    public function store(StoreFoo $request)
    {
        $foo = Foo::create($request->validated());
        foreach ($request->barIds as $barId) {
            $foo->bars()->create(['bar_id' => $barId]);
        }
    }
    

    我的问题是:有没有一种方法可以在没有循环的情况下做到这一点?我试过了 sync attach 但这些都不适用于这种情况。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Jonathon    6 年前

    我能想到的唯一方法是使用 saveMany 方法 HasMany 关系您可以创建 Bar 建模并将它们作为数组传递给 拯救很多人 方法,该方法将保存所有实体,并返回一个已创建实体的数组作为响应。

    $foo->bars()->saveMany([new Bar(['id' => 1]), new Bar(['id' => 2])]);
    

    也就是说,Laravel使用一个循环将这些模型一个接一个地保存在引擎盖下,因此它与您现在所做的没有太大不同。

    同样,还有一个 createMany 方法,您可以使用与 拯救很多人 但是,您可以提供属性数组,而不是提供新创建的模型。

        2
  •  0
  •   majid mohammadian    5 年前

    迁移表示例

    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');
    });
    

    模型日志。php文件

    class Log extends Model
    {
        const UPDATED_AT = null;
        protected $fillable = [
            'user_id',
            'type',
            'table',
            'row'
        ];
    
        public function logFields()
        {
            return $this->hasMany(LogField::class);
        }
    }
    

    模型记录场。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;
            });
        }
    

    希望我能帮助你理解这一点。