laravel 批量设置 fiilable的办法
家人们,之前用hyperf,在用命令创建model的时候,会自动填充文件的fillable,
但是laravel要自己写,字段很多,模型文件也很多,欲哭无泪啊
咋就是说我能不能通过动态方式去设置呢?
fillable 对model 内部是可见的,那我写个基类修改fillable不就好了
<?php
namespace App\Models;
use Illuminate\Support\Facades\Schema;
class Model extends \Illuminate\Database\Eloquent\Model
{
public function __construct()
{
parent::__construct();
// 设置fillable
$this->fillable = $this->getTableColumns($this->getTable());
}
protected function getTableColumns($tableName)
{
Schema::connection()->getColumnListing($tableName);
}
}
咋一看好像没问题,但是因为是基类,一步小心sql就执行的巨多
啊啊啊,全是查表结构对的
于是进行优化,我们可以把表名和字段映射成一个map,做成静态的,直接读取就好了
<?php
namespace App\Models;
use Illuminate\Support\Facades\Schema;
class Model extends \Illuminate\Database\Eloquent\Model
{
protected static $tableColumnsMap;
public function __construct()
{
parent::__construct();
// 设置fillable
$this->fillable = $this->getTableColumns($this->getTable());
}
protected function getTableColumns($tableName)
{
if (isset(self::$tableColumnsMap[$this->getTable()])) return self::$tableColumnsMap[$this->getTable()];
self::$tableColumnsMap[$this->getTable()] = Schema::connection()->getColumnListing($tableName);
return self::$tableColumnsMap[$this->getTable()];
}
}
啊啊啊,这下舒服了,舒服了!
本作品采用《CC 协议》,转载必须注明作者和本文链接
不应该用guarded空数组吗
直接guarded = ['id']不就行了~
protected static $unguarded = true;
禁用这个功能呢?虽然不太建议
Illuminate\Database\Eloquent\Concerns\GuardsAttributes
在这里设置的。
$guarded=[] 不就完事了嘛
FPM 下这么玩,会多查一次库啊。
为啥不起一个 Hyperf 项目,生成模型直接复制过来呢?
有点舍近求远了, $guarded 了解一下
boot下全局设置guarded 就完事了, :kissing_heart:
用Laravel Idea 插件,完美 :see_no_evil:
楼上都讲了
getTableColumns()
会导致每次请求都多一次类似select fields from ...
的查询,非常得不偿失。况且一些场景下information_schema
库的权限你也不一定有。较好的办法是用
$guarded
黑名单属性设置['id']
。// 在 app 目录下创建一个基类 BaseModel.php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
这样子的方法可以么 class BaseModel extends Model { protected $guarded = ['id']; }
// 然后在其他 Model 中继承这个基类 namespace App\Models;
use App\Models\BaseModel;
class User extends BaseModel { // User Model 的其他定义 }
我的guarded不生效,必须设置 $unguarded 才管用
使用
Laravel Idea
插件,焦点放到 $fillable 里,然后Control + Enter
选Add all fields
就自动生成了,不用这么麻烦我觉得这个做法有点离谱,你都这么做了,为什么不能一次查出来结果写进 model 呢,类似 @李铭昕 说的在别处生成 Model 复制过来的操作。
直接 $guarded = ['id']; 就可以了 只有在创建或者更新的时候才会查一次表的字段 如果你当前请求里面有多次 也只会在第一次的时候查一次表结构 因为是静态属性 查一次这个不影响什么性能 而且只是查表结构(一个项目中最多也就几百个表吧 也就几百条数据) 不是几百万的表数据 这个比更新或者创建操作快多了 这个是读一个是写 如果在laravel框架中还在乎这一次查询的话 建议使用octane 这样只会在最初的一次请求中就加载好了 只是会每次加字段的时候 需要reload一下octane 都加字段了 业务肯定也有调整 那肯定是避免不了这次重载的
我都是用AI工具帮我自动补全
1.先建立这个Trait
2.每个驱动都引用一下
3.增加以下Providers
这样生产环境就一直从缓存redis读取字段就可以了,避免一直读数据库,我不会排版不知道咋搞的,你凑合看吧
忘记在哪个帖子看到的,生成
fillable
然后复制到模型里楼上方法好像都不太科学,我觉得可以重写
make:model
命令,直接在生成model文件的时候,加到代码里面。还是这样来的舒服。yii 有个gii工具直接生成字段及字段注释 可以参考一下它的源码来弄
直接临时禁用掉黑名单不行吗?
编写 Command 来自动生成,对代码无侵入性