【问题标题】:Laravel 5 not updating correctlyLaravel 5 没有正确更新
【发布时间】: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。它会更具可读性和可理解性。
  • 我同意这只是我尝试使用复选框输入的众多选项之一。

标签: php laravel-5


【解决方案1】:

您可以在.blade 中尝试其他版本:

<input type='checkbox' id='has_services' name='has_services' class='form-control' value=1 
@if(isset($item))
    @if($item->has_services == 1)
        checked
    @endif
@endif
>

【讨论】:

  • 感谢您的建议。实际上,我之前对整个复选框都有一个 if 语句,一个没有选中,一个有。我只是在尝试不同的选择。我同意这种方式可读性较差,这恰好是我尝试过的众多选项之一。包括上面发布的变体在内的所有变体都没有改变结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-08
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多