【问题标题】:How to update related data One to One to Many at once on Laravel?如何在 Laravel 上一次对一对多更新相关数据?
【发布时间】:2019-11-18 12:30:36
【问题描述】:

我有这些相关的表:

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

这是我的模板控制器:

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) string(18) "更新 清单:“ int(0) 调用未定义的方法 照亮\数据库\雄辩\关系\HasOne::items() (1/1) BadMethodCallException 调用未定义的方法 Illuminate\Database\Eloquent\Relations\HasOne::items()

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

【问题讨论】:

  • 你的代码有效吗?
  • 不,不是,我只是客串,一定是这样。

标签: php laravel eloquent


【解决方案1】:

替换这个

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

有了这个

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

【讨论】:

    【解决方案2】:

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

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

    编码愉快!有需要就问我!

    【讨论】:

      猜你喜欢
      • 2018-09-26
      • 2015-04-12
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2018-01-28
      相关资源
      最近更新 更多