【laravel项目】@13 解决访问器与数据填充冲突
所用的知识点
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
- 点赞
- 收藏
- 关注作者
评论(0)