Laravel-admin 使用表单动态地保存一个关联模型(源码探究到功能实现)
时间:2019-01-17
本文章向大家介绍Laravel-admin 使用表单动态地保存一个关联模型(源码探究到功能实现),主要包括Laravel-admin 使用表单动态地保存一个关联模型(源码探究到功能实现)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
有时候我们使用Laravel-admin管理数据时,需要保存一些通过程序运算出来的数据,而不只是存储写在表单中的数据,也就是需要在保存数据前可以设置或改变数据。
比如存在这么个需求:
为了快速创建\管理一些测试数据,在Admin管理端创建一个用户账户的同时,创建相关的用户信息,用户订单、地址库等等一系列信息。
以这个需求中用户关联的数据量来说,每个数据都手动输入的话,效率太低了,所以只能自动创建。
所以实现的思路是这样的,表单中只有用户的基本信息,其它的订单、地址都是在执行store函数前自动生成的,然后关联保存即可。
先看Form.php的store函数源码:
public function store()
{
$data = Input::all();
......
}
数据来源是request对象,所以,轻而易举地想到:
在store之前往request中塞入订单、地址的关联数据
这个数据的格式在我的另一篇博文中有详细解释:laravel-admin grid中使用switch操作一对一关联属性,但是执行提交后发现并没有成功保存,于是走一波源码调试。
首先看到更新关联模型数据的数据:
public function store()
{
......
DB::transaction(function () {
$inserts = $this->prepareInsert($this->updates);
foreach ($inserts as $column => $value) {
$this->model->setAttribute($column, $value);
}
$this->model->save();
//在这里保更新关联模型
$this->updateRelation($this->relations);
});
......
}
继续进入updateRelation方法跟踪:
protected function updateRelation($relationsData)
{
foreach ($relationsData as $name => $values) {
if (!method_exists($this->model, $name)) {
continue;
}
$relation = $this->model->$name();
//在这里判定是否是一对一
$oneToOneRelation = $relation instanceof Relations\HasOne
|| $relation instanceof Relations\MorphOne
|| $relation instanceof Relations\BelongsTo;
//在这里做一个预处理
$prepared = $this->prepareUpdate([$name => $values], $oneToOneRelation);
//预处理的结果为空则没有后续处理
if (empty($prepared)) {
continue;
}
经过打断点调试,发现我在store之前插入的订单、地址关联数据并没有通过预处理,所以再来看看prepareUpdate预处理是什么鬼:
protected function prepareUpdate(array $updates, $oneToOneRelation = false)
{
$prepared = [];
/** @var Field $field */
//$this->builder->fields() 就是表单字段相关属性
foreach ($this->builder->fields() as $field) {
$columns = $field->column();//这个是字段名称了
// If column not in input array data, then continue.
if (!array_has($updates, $columns)) {//关键在这,如果表单字段不在request的数据中就过滤掉
continue;
}
if ($this->invalidColumn($columns, $oneToOneRelation)) {
continue;
}
$value = $this->getDataByColumn($updates, $columns);
$value = $field->prepare($value);
if (is_array($columns)) {
foreach ($columns as $name => $column) {
array_set($prepared, $column, $value[$name]);
}
} elseif (is_string($columns)) {
array_set($prepared, $columns, $value);
}
}
return $prepared;
}
在上面的注释中,清楚地表明了一个状况:
form表单的提交保存只能保存表单中有的字段,不然都会被过滤掉。
所以,我们需要让Laravel-admin认为我们表单中有订单、地址关联字段,根据我们的需求,很容易想到使用hidden组件:
只要把所有关联关系需要更新的字段都使用hidden列出来即可,不需要赋值
而且在store前,如果根据某些条件不需要保存这个关联关系的话,直接使用request的offsetUnset将那个关联关系整体删除即可。
- eclipse tomcat下网页修改不生效
- 【插件开发】—— 14 Site is incorrect!编辑器启动报错!
- Java魔法堂:Date与日期时间格式化
- Java魔法堂:打包知识点之META-INF/MAINFEST.MF
- WordPress快速建站
- 大数据时代下的生活
- 【Spring实战】—— 1 入门讲解
- 博客园小技巧
- JS魔法堂:关于元素位置和鼠标位置的属性
- MyBatis魔法堂:Insert操作详解(返回主键、批量插入)
- Winodws安装系统时,通过安装磁盘进行分区
- Eclipse安装SVN插件
- JS魔法堂:IE5~9的Drag&Drop API
- mysql 5.7版本目录无data文件夹的解决办法
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- 【Java8新特性】04 详解Lambda表达式中Predicate Function Consumer Supplier函数式接口
- ubuntu下的进程控制系统————Supervisor
- 如何高效、快速、准确地完成ML任务,这4个AutoML库了解一下
- [译]如何用 Typescript 写一个完整的 Vue 应用程序
- Docker上手系列:Docker入门hello world
- 前端应该知道的 HTTP 知识
- React 学习笔记(基础篇)
- 前端性能优化《一》——Chrome Performance 页面性能调试
- 【Vue 进阶】从 slot 到无渲染组件
- 一个合格的中级前端工程师应该掌握的 20 个 Vue 技巧
- Vue 3 任意传送门——Teleport
- @JsonCreator自定义反序列化函数-JSON框架Jackson精解第5篇
- 不靠谱的 console
- 使用ThreadLocal和ArgumentResolver方便开发
- 【Java8新特性】05 使用Optional取代null