【发布时间】:2018-01-11 18:52:51
【问题描述】:
我正在使用 Laravel 5.4 和 PHP 7.1 更新我的一个模型时遇到问题。我对创建和更新使用相同的形式,创建按预期工作,但更新没有。奇怪的是我有另一个完全按预期工作的模型,但我找不到我使用的代码之间的任何区别。这是我的第一个 Laravel 项目,我是自学成才的,所以我的代码中可能有一些不好的做法,我欢迎任何建设性的批评。
当我尝试将复选框属性更新为 false 时,它总是返回 true。当我创建初始对象时,我得到了复选框的正确值 true 和 false,但是如果布尔值为 true,那么我不能将其设置为 false。我不确定这是刀片还是我的代码中的问题。在控制器中,我在更新之前使用了 dd($item) 并且即使未选中复选框,该值也为 true。在模型中,我有一个强制转换来确保属性是布尔值,在模型中有一个 mutator 来确保值为 0 或 1,请求中有一个类似的特性来确保值为 0 或 1。这两个属性我我遇到了 has_accessories 和 has_services 的问题。
我在更新价格字段时也遇到了问题,如果价格值中有逗号,我会在更新时收到错误消息。有趣的是,当我在更新之前执行 dd($item) 时,值 not 中是否有逗号。在初始创建时,当价格中有逗号时,我可以保存对象。当我在 html 页面中省略逗号时,就没有问题了。模型中有一个修改器,可以删除请求中的任何逗号或 $ 和类似代码。我遇到问题的属性是价格。
这是模型中的相关代码:
class Item extends Model
{
protected $fillable = ['item_type_id', 'item_category_id', 'item_condition_id', 'name',
'description', 'serial_number', 'serial_accessory', 'size', 'price',
'has_accessories', 'has_services', 'manafacturer',
'manufacturer_serial_number', 'refrigerant_type'];
protected $guarded = ['id'];
protected $dates = ['created_at', 'updated_at'];
protected $casts = ['has_accessories' => 'boolean', 'has_services' => 'boolean'];
// mutators - also located in Requests\ItemRequest (custom form validation)
protected function setPriceAttribute($value)
{
if (isset($value)) {
$this->attributes['price'] = str_replace(',', '', $value);
$this->attributes['price'] = str_replace('$', '', $value);
} else {
$this->attributes['price'] = 0;
}
}
protected function setHasAccessoriesAttribute($value) { $this->attributes['has_accessories'] = isset($value) ? $value : FALSE; }
protected function setHasServicesAttribute($value) { $this->attributes['has_services'] = isset($value) ? $value : FALSE; }
// accessors
protected function getPriceAttribute($value) { return isset($value) ? number_format(round($value, 2), 2, '.', ',') : 0; }
这是来自我的控制器的相关代码:
public function store(ItemRequest $itemRequest)
{
// dd($_POST);
Item::create($itemRequest->request->all());
session()->flash('alert', $itemRequest->request->get('name').' created.');
return redirect('items');
}
public function update(Request $itemRequest, Item $item)
{
//dd($item);
$item->update($itemRequest->request->all());
session()->flash('alert', $item->name.' updated.');
return back();
}
这是请求:
class ItemRequest extends FormRequest
{
public function authorize()
{
// only allow if user is logged in
return Auth::check();
}
public function rules()
{
return [
'item_type_id' => 'required|integer|exists:item_types,id',
'item_category_id' => 'required|integer|exists:item_categories,id',
'item_condition_id' => 'required|integer|exists:item_conditions,id',
'name' => 'required|between:1,50|string',
'description' => 'required|string',
'serial_number' => 'nullable|max:25|alpha_dash',
'serial_accessory' => 'nullable|max:10|alpha_dash',
'size' => 'nullable|alpha_num',
'price' => 'nullable|numeric',
'has_accessories' => 'required|boolean',
'has_services' => 'required|boolean',
'manufacturer' => 'nullable|string|max:30',
'manufacturer_serial_number' => 'nullable|string|max:30',
'refrigerant_type' => 'nullable|string|max:30'
];
}
protected function prepareForValidation()
{
$this->sanitizeInput();
return parent::getValidatorInstance();
}
private function sanitizeInput()
{
// get the input
$input = array_map('trim', $this->all());
$input['has_accessories'] = isset($input['has_accessories']) ? $input['has_accessories'] : FALSE;
$input['has_services'] = isset($input['has_services']) ? $input['has_services'] : FALSE;
$input['price'] = empty($input['price']) ? null : str_replace(',', '', $input['price']);
$this->replace($input);
}
}
这是相关的刀片代码:
<div class='col-xs-2 col-sm-2 col-md-1 form-group margin_under_border'>
<label for='price' class='form-label'>Price</label>
</div>
<div class='col-xs-4 col-sm-4 col-md-2 form-group margin_under_border'>
<input type='text' id='price' name='price' value="{{ old('price', isset($item) ? $item->price : null) }}" class='form-control'>
</div>
<div class='col-xs-4 col-sm-4 col-md-2 form-group margin_under_border'>
<label for='has_accessories' class='form-label'>Has Accessories</label>
</div>
<div class='col-xs-1 col-sm-1 col-md-1 form-group margin_under_border'>
<input type='checkbox' id='has_accessories' name='has_accessories' class='form-control' value=1 {{ (old('has_accessories', isset($item) ? $item->has_accessories : 1) == 1)? 'checked' : '' }}>
</div>
<div class='col-xs-1 col-sm-1 hidden-md hidden-lg'>
</div>
<div class='col-xs-4 col-sm-4 col-md-2 form-group margin_under_border'>
<label for='has_services' class='form-label'>Has Services</label>
</div>
<div class='col-xs-1 col-sm-1 col-md-1 form-group margin_under_border'>
<input type='checkbox' id='has_services' name='has_services' class='form-control' value=1 {{ (old('has_services', isset($item) ? $item->has_services : 1) == 1) ? 'checked' : '' }} >
</div>
感谢您对此提供的任何帮助。被这么简单的动作卡住真是令人沮丧。
更新:当我使用 tinker 时,我可以成功地将模型中的布尔属性设置为 false。当价格属性中有逗号时,我无法设置它。
我已经注释掉了我的模型和请求中的所有代码,我将更新更改为 $item->update() 而不是通过请求运行它,并且我将复选框代码更改回原来的:
<div class='col-xs-1 col-sm-1 col-md-1 form-group margin_under_border'>
@if (old('has_accessories', isset($item) ? $item->has_accessories : 1) == 1)
<input type='checkbox' id='has_accessories' name='has_accessories' class='form-control' value=1 checked>
@else
<input type='checkbox' id='has_accessories' name='has_accessories' class='form-control' value=1>
@endif
</div>
我仍然遇到同样的问题。我认为这可能是代码中某处的错字导致它,但它不能比更新语句更简单。我无法理解的是,如果它是复选框代码,那么为什么它在创建时按预期工作,但在更新时却没有?
当我执行 dd($item) 时,未选中复选框的值不正确(如果之前为 true),但是当我执行 dd($_POST) 时,值是正确的。
【问题讨论】:
-
为什么不在视图中使用
@if。它会更具可读性和可理解性。 -
我同意这只是我尝试使用复选框输入的众多选项之一。