【laravel项目】@13 解决访问器与数据填充冲突

举报
原来是咔咔 发表于 2022/03/27 02:23:51 2022/03/27
【摘要】 解决访问器与数据填充冲突问题 所用的知识点素材需要数据库GoodsCategory模型创建GoodsCategoryTableSeeder.php数据填充文件创建GoodsCategoryObse...

所用的知识点

1.迁移文件的创建
2.数据填充
3.通过观察者监听模型事件
4.注册观察者
5.模型

素材需要

数据库

字段 value
id 分类id
name 分类名
parent_id 父级id
image 分类图标
level 当前分类的等级
sort 排序
possess 该分类的所有父类

GoodsCategory模型

在这里插入图片描述
在category定义一个与上级以及子级的模型关联。然后添加三个获取器;1.获取所有的上级id,2.根据获取的id获取子级的所有上级,并且根据level排序。 至于之后一个只是获取所有的上级名称

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 商品分类
 */
class GoodsCategory extends Model
{
    protected  $fillable = ['name', 'category_image'];

    public function parent()
    {
        //反向关联
        return $this->belongsTo(GoodsCategory::class);
    }

    public function children() {
        //一对多
        return $this->hasMany(GoodsCategory::class, 'parent_id');
    }

    //定义一个访问器,获取所有祖先类目的ID值
    public function getPossessIdsAttribute()
    {
        //array_filter 将数组中的空值移除
        return array_filter(explode('-', trim($this->possess, '-')));
    }

    //定义一个访问器,获取祖先类目并按层级排序
    public function getAncestorsAttribute()
    {
        return GoodsCategory::query()
            ->whereIn('id', $this->possess_ids)
            //按层级排序
            ->orderBy('level')->get();
    }

    //定义一个访问器,获取以 - 为分隔的所有祖先类目的名称以及当前类目的名称
    public function getFullNameAttribute()
    {
        return $this->ancestors //获取所有祖先类
            ->pluck('name') //获取祖先类目的name 字段为一个数组
            ->push($this->name)//获取当前类目的 name 字段加到数组的末尾
            ->implode(' - '); //用 - 符合将数组的值组成一个字符串
    }

    public function getLevelAttribute($value) {
        $data = [
            '0' => '根目录',
            '1' => '二级',
            '2' => '三级',
        ];
        return (is_null($value)) ? $data : $data[$value];
    }

    /**
     * 测试方法
     * @return [type] [description]
     */
    public function test() {
        $category = GoodsCategory::where('id', 10)->first();
        $data = $category->ancestors->toArray();
        return $data;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

创建GoodsCategoryTableSeeder.php数据填充文件

命令:php artisan make:seeder GoodsCategoryTableSeeder
在这里插入图片描述

<?php
use App\Models\GoodsCategory;
use Illuminate\Database\Seeder;

class GoodsCategoryTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $categories = [
            [
                'name'     => '手机配件',
                'sort'     => '0',
                'children' => [
                    [
                        'name'     => '手机壳',
                        'sort'     => '0',
                        'children' => [
                            [
                                'name' => '华为V10手机',
                                'sort'     => '0',
                            ],
                            [
                                'name' => '小米',
                                'sort'     => '1',
                            ],
                        ],
                    ],
                    [
                        'name'     => '数据线',
                        'sort'     => '4',
                        'children' => [
                            [
                                'name' => '苹果数据线',
                                'sort'     => '0',
                            ],
                            [
                                'name' => '安卓数据线',
                                'sort'     => '1',
                            ],
                        ],
                    ],
                    [
                        'name'     => '耳机',
                        'sort'     => '0',
                        'children' => [
                            [
                                'name' => '有线耳机',
                                'sort'     => '1',
                            ],
                            [
                                'name' => '蓝牙耳机',
                                'sort'     => '0',
                            ],
                        ],
                    ],
                ],
            ],
            [
                'name'     => '六星果园',
                'sort'     => '0',
                'children' => [
                    [
                        'name'     => '国产水果',
                        'sort'     => '0',
                        'children' => [
                            [
                                'name' => '苹果',
                                'sort'     => '0',
                            ],
                            [
                                'name' => '梨',
                                'sort'     => '1',
                            ],
                        ],
                    ],
                ]
            ]
        ];
        foreach ($categories as $data) {
            $this->createCategory($data);
        }

    }
    public function createCategory($data, $parent = null)
    {
        // 创建一个分类
        $category = new GoodsCategory([
            'name' => $data['name'],
            'sort' => $data['sort'],
        ]);
        // 如果有父级参数,代表有父类目
        if (!is_null($parent)) {
            // 将模型实例与给定的父实例关联。
            $category->parent()->associate($parent);
        }
        // 保存到数据库
        $category->save();
        // 如果有children字段并且 children字段是一个数组
        if (isset($data['children']) && is_array($data['children'])) {
            foreach ($data['children'] as $child) {
                $this->createCategory($child, $category);
            }
        }
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

创建GoodsCategoryObserver.php观察者

命令:php artisan make:observer GoodsCategoryObserver --model=GoodsCategory
在这里插入图片描述

<?php

namespace App\Observers;

use Log;
use App\Models\GoodsCategory;

class GoodsCategoryObserver
{
    public function creating(GoodsCategory $goodsCategory) {
        //如果创建的是一个根类目
        if (is_null($goodsCategory->parent_id)) {
            //讲层级设置为0
            $goodsCategory->level = 0;
            //将path 设为 -
            $goodsCategory->possess = '-';
        }else {
            //将层级设为父类目层级 + 1
            $goodsCategory->level = $goodsCategory->parent->level +1;
            // 将path 设为父级目的的PATH 追加父级的id 并最后 跟上一个  -  分隔符
            $goodsCategory->possess = $goodsCategory->parent->possess.$goodsCategory->parent_id.'-';

        }
    }
    /**
     * Handle the goods category "created" event.
     *
     * @param  \App\GoodsCategory  $goodsCategory
     * @return void
     */
    public function created(GoodsCategory $goodsCategory)
    {

    }

    /**
     * Handle the goods category "updated" event.
     *
     * @param  \App\GoodsCategory  $goodsCategory
     * @return void
     */
    public function updated(GoodsCategory $goodsCategory)
    {
        //
    }

    /**
     * Handle the goods category "deleted" event.
     *
     * @param  \App\GoodsCategory  $goodsCategory
     * @return void
     */
    public function deleted(GoodsCategory $goodsCategory)
    {
        //
    }

    /**
     * Handle the goods category "restored" event.
     *
     * @param  \App\GoodsCategory  $goodsCategory
     * @return void
     */
    public function restored(GoodsCategory $goodsCategory)
    {
        //
    }

    /**
     * Handle the goods category "force deleted" event.
     *
     * @param  \App\GoodsCategory  $goodsCategory
     * @return void
     */
    public function forceDeleted(GoodsCategory $goodsCategory)
    {
        //
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

创建数据库迁移文件

php artisan make:mmigration create_goods_category_table --create=goods_category
在这里插入图片描述

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGoodsCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('goods_categories', function (Blueprint $table) {
            $table->increments('id')->comment('商品类别主键id');
            $table->string('name')->comment('类别名称');
            $table->integer('parent_id')->default(0)->comment('父级类别id');
            $table->string('image')->nullable()->comment('分类图片');
            $table->integer('level')->default(0)->comment('分类等级');
            $table->integer('sort')->default(0)->comment('分类排序');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('goods_categories');
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

注册观察者

命令:php artisan make:provider ModelObserverServiceProvider
在这里插入图片描述

<?php

namespace App\Providers;

use App\Observers\GoodsCategoryObserver;
use App\Models\GoodsCategory;
use Illuminate\Support\ServiceProvider;

class ModelObserverProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        GoodsCategory::observe(GoodsCategoryObserver::class);
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

然后在app里边注册进去即可
在这里插入图片描述

重现数据填充与访问器冲突

执行数据填充命令

php artisan db:seed --class=GoodsCategoryTableSeeder
在这里插入图片描述
然后打开数据库
在这里插入图片描述

日志检测问题

我们会发现我们自定义的数据都没有进去,只进去了第一行,这是为什么呢!
我们可以看到有个一报错信息是 A non-numeric value encountered,并且报到了观察者的19行,我们在这里写个日志看看原因
在这里插入图片描述
在把数据填充的命令执行一次
php artisan db:seed --class =GoodsCategoryOberserver
同样也给出了这里的报错信息,那么咱们看看这level字段到底怎么回事
在这里插入图片描述

检测level字段的问题

可以看到在模型里边定义了一个访问器来重新定义了level字段,那么问题就在这里了,这个时候我们在注释了以后去执行填充命令
在这里插入图片描述
执行
在这里插入图片描述
查看数据库
这个时候就是可以的了
在这里插入图片描述

解决访问器与数据填充时的冲突

虽然我们在上边解决了这个问题,但是我们定义的这个访问器是在后台显示数据的时候使用的。其实数据填充出现的问题,也就是我们在后台进行数据添加时会报出的问题,所以这个问题不是一个注释解决的

1.在模型里边定义一个虚拟字段
在这里插入图片描述
2.修改之前的访问器
在这里插入图片描述
3.然后在执行填充命令
在这里插入图片描述
4.查看数据库
在这里插入图片描述
5.打开后台查看数据
在这里插入图片描述

解决设置的访问器不能正常使用

我们在添加了虚拟属性后, 我们的数据填充是好了,但是我们在后台获取数据时并没有作用
这个时候还需要一步操作,那就是把字段也给换成自定义的字段
在这里插入图片描述
这个时候在来查看,就没有问题了
在这里插入图片描述

文章来源: blog.csdn.net,作者:咔咔-,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/fangkang7/article/details/95177681

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200