使用 FormData 将数据从 Vue 传递到 Laravel 的整数问题

Issue with Integers passing data from Vue to Laravel using FormData

我成功地将使用 Vue 2 的数据库更新为使用 Axios 的 Laravel 8 控制器。但是,我在尝试将整数传递到我的数据库时卡住了。

我的数据库有一列,'number_of_searches',它必须是一个整数。

Laravel 迁移看起来像这样:

$table->integer('number_of_searches')->nullable();

模型看起来像这样:

class Product extends Model
{
    protected $fillable = [
        'product_title', 
        'number_of_searches' => 'integer',
    ];
}

我的 Vue updateProduct() 函数使用了 FormData 并附加了来自表单的值。它看起来像这样:

updateProduct(product){
   let data = new FormData();
   data.append('_method', 'PATCH');
   data.append('product_title', product.product_title);
   data.append('number_of_searches', product.number_of_searches);
   axios.post('/api-route-to-update/product_id/', data)
   .then(function (response) {
      console.log(response);
      })
   .catch(function (error) {
      console.log(error);            
       });
}

我的更新控制器是这样的:

public function update(Request $request, $product_id){
   $product = Product::findOrFail($product_id);
   $product->update($request->all());
   $product->save();
}

我可以有任意多的输入字段,只要它们是字符串,它就可以完美地工作。但是,当我在组件中使用数字输入字段时,例如:

<input v-model="product.number_of_searches" type="number" min="1" max="999">

将从 axios 传递到我的控制器的生成的 json 如下所示:

{ "id": 5, "product_title": "The Product Title will work great", "number_of_searches": "222"}

您会注意到 'number_of_searches' 作为字符串传递,因此我的数据库失败,因为它是错误的数据类型,它需要一个整数。阅读文档和其他线程后,FormData 似乎总是 return 字符串,我必须在服务器端处理它。

所以我所做的是进入后端 updateProduct() 方法并尝试修改请求。

首先我尝试了一些方法,例如:

//this one
$requestData = $request->all();
$requestData['number_of_searches'] = 123;

//also this one
$request->merge(['number_of_searches' => 123]);

//and this
$data = $request->all();
$data['number_of_searches'] = 123;

无数小时后,我无法修改原始请求。经过一番研究,似乎请求是受保护的,不能修改,这是有道理的。因此,我尝试创建一个克隆 $request->all() 的新请求,如下所示:

$new_request = new Request($request->all());
$new_request->merge(['number_of_searches' => 123]);

但是我强制覆盖失败了'number_of_searched'

我的问题是:

在这种情况下我应该完全远离 FormData 吗?您建议使用什么方法通过 axios 或 fetch 传递具有整数或浮点数或其他数据类型的表单?或者我做错了什么?我很难相信 FormData 只会发送字符串(在使用 axios 之前使 parseInt 无用)。我确定我从一开始就做错了。

另一方面,也许我需要在接收数据时完全改变我在控制器中的方法。我正在开发一个包含很多字段的应用程序,我喜欢 $request->all() 因为它简化了我想做的事情。我不介意在服务器端使用 intval,仅此而已,但它似乎过于复杂。

在 Vue 方面,您可以在 v-model 上使用 number 修饰符以确保它不会将值转换为字符串:

v-model.number="product.number_of_searches"

在请求端,您可以使用$request->merge覆盖请求中的值

$request->merge([
  'number_of_searches' => (int) $request->get('number_of_searches');
]);

boot 方法中 updating 挂钩的模型端,您可以确保在保存时将值转换为 int:

static::updating(function ($model) {
    $model->number_of_searches = (int) $model->number_of_searches;
});

这应该给你一个完整的结尾。