Request::intersect (...) 一个可以让你初步远离意大利面条的函数
不想抛弃意大利面条式编程的程序员肯定没有好的苍老师
假设让你更新一条数据的部分数据的时候
PATCH /records/{id}
{
"title": "新的标题",
"label": "新的标签"
}
Before
以前你可能是这样的这样
$record = Record::findOrFail($id);
if ($request->has('title')) {
$record->title = $request->title;
}
if ($request->has('label')) {
$record->label = $request->label;
}
if ($request->has('year')) {
$record->year = $request->year;
}
if ($request->has('type')) {
$record->type = $request->type;
}
$record->save();
After
现在你可以尝试一下这样。
这里用到了 request 中的 intersect 方法
$record = Record::findOrFail($id);
$record->update($request->intersect([
'title',
'label',
'year',
'type'
]));
所以借用 Adam 的一张图,最后效果就是这样
原理
实际上,上面的例子用到了 request 中的 intersect 方法,而这个方法已经对数据进行了一次 array_filter 筛选。
/**
* Intersect an array of items with the input data.
*
* @param array|mixed $keys
* @return array
*/
public function intersect($keys)
{
return array_filter($this->only(is_array($keys) ? $keys : func_get_args()));
}
Tips: 在 Laravel 5.4,Taylor 重新梳理了代码结构,把一些方法放到了
Illuminate/Http/Concerns中。例如这里的intersect方法是在Illuminate/Http/Concerns/InteractsWithInput.php。所以 Laravel 真的是越读越有意思。
本帖已被设为精华帖!
本帖由 Summer
于 9年前 加精
关于 LearnKu
其实这个函数在5.3的时候就有了,只不过没有写进文档而已,而在 Laravel 5.4 中已经把这个函数写在文档了。等待社区的 Laravel 5.4 的中文文档吧
早就应该有的功能,@Aufree 昨天还在讲 laravel 的这点设计不如 rails
其实这个功能因为是用
array_filter,所以在某些场景还是会有一些小问题的,例如true和false的更新,就问你怎么破@milkmeowo 如果结合新的中间件
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull就不会有问题的,因为空字符串已经被过滤成null了,再者,表单请求的时候所有的内容格式为 string , 所以不会有true/false存在了。 当然了,在写 API 时候content-type: application/json这类请求的时候还是不能直接这样用这个 feature 的。@milkmeowo 还有一点差点忘记了,值为
0,0.0的也会被过滤,哈哈,所以如果有这个场景的时候还是要小心使用 :laughing:@overtrue 对的
null,empty和0都会被过滤,在content-type: application/json这类请求就会有true/false这种场景,所以如果要用,则需要考虑这类场合了。然后我今天发现了 themsaid 大大PR了一个
Request::pick()方法:joy:[5.4] Add Request::pick()
看起来就像是用来应对某些场合,所以其实这到底是刚需还是伪需求?
@overtrue
所以这三个方法的区别
结果:
@milkmeowo 感觉是伪需求
我自己写了一个方法,会从模型文件反查 title 和 label 的数据类型,长度限制,是否必填等,夹在 Validation 里,过了验证几乎就没问题了。
下一步再来指定某些列为文件上传型,下拉选项型,好了,连 CRUD 页面都可以自动生成了。
想问一下 这个和
$request->only()有什么不同之处@zhaohehe 仔细看 7 楼 我回复的代码,如果使用
$request->only()方法,即使数据不在 request data 中,only方法也会将数据设置为null,而其他两个示例则会过滤掉不在 request data 中的数据。@qufo 可以把你的想法,写出来和大家共享一下
@milkmeowo 在写,从数据表直接生成CRUD,比较适合后台管理,数据库驱动的项目。写好,完善了,再拿出来吧,不急。
@milkmeowo 了解了 多谢
时间一晃到了 L5.5 时代,only 变成了 intersect,而all 已可以传入参数,包含了旧 only 的功能
yii2有这种写法吗