如何在Laravel上一次一对多更新相关数据?

时间:2019-07-09 01:31:24

标签: php laravel eloquent

我有以下相关表:

[Template] ---- [HasOne]--> [Checklist] ---- [HasMany]--> [Items]

我想知道如何在一个关联过程中更新这些相关数据,以便可以顺利完成。

这是我的模特:

模板:


<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Template extends Model
{
    protected $table = 'templates';
    protected $fillable = [
        'name'
    ];
    public function checklist(){
        return $this->hasOne(Checklist::class,'template_id');
    }
}

检查清单

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Item;
use Carbon\Carbon;

class Checklist extends Model
{
    protected $table = 'checklists';
    protected $fillable = [
        'template_id',
        'description',
        'due_interval',
        'due_unit'
    ];    
    public function template(){
        return $this->belongsTo(Template::class,'template_id');
    }
    public function items(){
        return $this->hasMany(Item::class,'checklist_id');
    }
}

项目

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class Item extends Model
{
    protected $table = 'items';
    protected $fillable = [
        'description',
        'urgency',
        'due_interval',
        'due_unit'
    ];
    public function checklists(){
        return $this->belongsTo(Checklist::class,'checklist_id');
    }
}

这是我的 TemplateController:

public function update(Request $request,$templateId)
{
    $req                    = json_decode($request->getContent(),true);
    $data                   = $req['data'];
    $findtemplate           = Template::find($templateId)->first();
    $exetemplate            = $findtemplate->update(
                            [
                                'name'   => $data['name']

                            ]
    );
    var_dump('Update Template: ',$exetemplate);

    $exechecklist           = $findtemplate->checklist()->update(
                            [
                                'description'   => $data['checklist']['description'],
                                'due_interval'  => $data['checklist']['due_interval'],
                                'due_unit'      => $data['checklist']['due_unit']
                            ]
    );
    var_dump('Update Checklist: ',$exechecklist);

    $execitem               = $findtemplate->checklist()->items()->update(
                            [
                                'description'   => $data['items']['description'],
                                'urgency'       => $data['items']['urgency'],
                                'due_interval'  => $data['items']['due_interval'],
                                'due_unit'      => $data['items']['due_unit']
                            ]
    );
    var_dump('Create Items: ',$execitem);
}

以上代码显示了以下错误:

  

string(17)“更新模板:” bool(true)字符串(18)“更新   清单:“ int(0)调用未定义的方法   照亮\ Database \ Eloquent \ Relations \ HasOne :: items()(1/1)   BadMethodCallException调用未定义的方法   Illuminate \ Database \ Eloquent \ Relations \ HasOne :: items()

我想用最佳实践方法更新这些相关表。这该怎么做?请帮忙吗?

2 个答案:

答案 0 :(得分:0)

替换此

$findtemplate->checklist()->items()->update

与此

$findtemplate->checklist->items()->update()

答案 1 :(得分:0)

首先在模型之间创建关系:

// app\Template.php
class Template extends Model
{
    protected $fillable = ['name'];
    public function checklist(){
        return $this->hasOne(Checklist::class);
    }

    public function items(){
        return $this->hasManyThrough(Item::class,Checklist::class,'template_id','checklist_id','id','id');
    }
}
// app\Checklist.php
class Checklist extends Model
{
    protected $fillable = ['template_id','description','due_interval','due_unit'];
    public function template(){
        return $this->belongsTo(Template::class);
    }
    public function items(){
        return $this->hasMany(Item::class);
    }
}
// app\Item.php
class Item extends Model
{
    protected $fillable = ['checklist_id','description','urgency','due_interval','due_unit'];
    public function checklist(){
        return $this->belongsTo(Checklist::class);
    }
}

然后您可以通过Laravel正常方式更新表的关系数据,我使用一些示例数据,您可以对其进行自定义以适合您的项目:

// app\Http\Controllers\YourController.php 
class YourController extends Controller
{
    public function index(){
        $templateId = 1;
        $data = [];
        $data['name'] = "Template name update1";
        $data['checklist']['description'] = "Description checklist update1";
        $data['checklist']['due_interval'] = 99991111;
        $data['checklist']['due_unit'] = 88881111;
        $data['items']['description'] = ["Description item1 update1","Description item2 update1"];
        $data['items']['urgency'] = [9,1];
        $data['items']['due_interval'] = [66661111,44441111];
        $data['items']['due_unit'] = [555511111,33331111];
        $this->test_update($data, $templateId);
        return view('template');
    }
    public function test_update($data, $templateId){
        $findtemplate = Template::find($templateId);
        $exetemplate  = $findtemplate->update(['name'=> $data['name']]);
        $checklist = $findtemplate->checklist()->first();
        $exechecklist= $checklist->update(
            [
                'description'   => $data['checklist']['description'],
                'due_interval'  => $data['checklist']['due_interval'],
                'due_unit'      => $data['checklist']['due_unit']
            ]);
        $execitem = $findtemplate->items()->delete(); // remove old datas relate with $findtemplate, remove this line if you want to skip them!
        foreach($data['items']['description'] as $key=>$value){
            $i = [];
            $i ['checklist_id'] = $checklist->id;
            $i ['description'] = $value;
            $i ['urgency'] = $data['items']['urgency'][$key];
            $i ['due_interval'] = $data['items']['due_interval'][$key];
            $i ['due_unit'] = $data['items']['due_unit'][$key];
            $inew = new Item($i);
            $checklist->items()->save($inew);
        }
        var_dump('Successfull!');
    }
}

祝您编程愉快!问我是否需要!