如何在模型绑定中使用带有 Laravel 的复选框组

Posted

技术标签:

【中文标题】如何在模型绑定中使用带有 Laravel 的复选框组【英文标题】:How to use a checkbox group with Laravel's from model binding 【发布时间】:2014-11-27 14:24:28 【问题描述】:

我正在尝试将复选框组作为序列化字符串保存在我的主模型的数据库表中。 AudienceGroups 只是我主要雄辩模型的一个属性。如果我只是这样做

Form::checkbox('AudienceGroups[]', 'preschool');
Form::checkbox('AudienceGroups[]', 'elementary');

在我的模型中没有逻辑,那么数据库列设置为字符串Array。如果我去掉括号并只使用Form::checkbox('AudienceGroups', 'preschool');,那么该列将设置为最后一个复选框的值,在我的例子中是“seniors”。

如果我在保存模型实例之前序列化数组,它会像预期的那样保存为序列化数组,但我无法让它在页面加载时重新填充正确的复选框(来自旧输入或来自保存的模型)。

我应该如何解决这个问题?自己序列化数组,然后用我自己的逻辑控制第三个参数到Form::checkbox(),它控制检查状态?如果是这样,有人可以帮我解决这个问题。我尝试使用 Input::old 和 in_array 进行尝试,但始终无法正常工作。

谢谢

【问题讨论】:

【参考方案1】:

首先,将序列化的属性放在一列中并不是最佳解决方案。您不应该这样做,因为如果您以后想在 DB 中搜索这些数据,您将无法这样做。

我认为你的问题的解决方案并不复杂。

我准备了两条简单的路线:

Route::get('/checkbox',function() 

    // normally you would get it from model and unserialize it
    $fromModel = ['preschool','elementary','something'];

    return View::make('form')->with('fromModel',$fromModel);

);

Route::post('/checkbox-post',function() 

    $agroups = Input::get('AudienceGroups');

    foreach ($agroups as $item) 
        echo $item."<br />";

    
    $toModel = serialize($agroups);

    echo $toModel;

    // now you insert it into model

);

和形式:

 Form::open(['url' => 'checkbox-post', 'role' => 'form']) 
Preschool:
Form::checkbox('AudienceGroups[]', 'preschool', (in_array('preschool', $fromModel) ? true : false))<br />

Elementary:
Form::checkbox('AudienceGroups[]', 'elementary', (in_array('elementary', $fromModel) ? true : false))<br />

Something else:
Form::checkbox('AudienceGroups[]', 'somethingelse', (in_array('somethingelse', $fromModel) ? true : false))<br />

Something:
Form::checkbox('AudienceGroups[]', 'something', (in_array('something', $fromModel) ? true : false))<br />

Form::submit('Send')

 Form::close() 

您可以使用http://localhost/yourproject/checkbox 运行它 - 表单已初始化并选中了 3 个复选框。在刀片中,您可以使用 in_array 来检查正确的复选框,在 POST 路由中,您可以简单地使用此 Input::get('AudienceGroups') 作为数组并对其进行序列化。

【讨论】:

感谢您的详细回复。但是,由于您的示例没有使用表单模型绑定,因此它不受我面临的问题的影响。然而,它确实激励我继续探索潜在的问题,而不是放弃复选框组的表单宏。 另外,序列化的列是由于现有系统造成的。不是我的设计。【参考方案2】:

更新

看起来 html 帮助程序已从核心存储库中删除,但从未得到修复。 https://github.com/laravel/framework/issues/5078


我遇到的问题是 Form::checkbox() 的第三个参数在使用表单模型绑定时没有按预期工作。

laravel documentation 声明值优先级是:

    会话闪存数据(旧输入) 显式传递值 模型属性数据

但是,如果您查看/Illuminate/Html/FormBuilder.php 中的 getCheckboxCheckedStatus(),您会发现检查状态的优先级实际上是:

    旧输入 模型数据

    显式传递的值

    protected function getCheckboxCheckedState($name, $value, $checked)
    
        if (isset($this->session) && !$this->oldInputIsEmpty()
            && is_null($this->old($name))
        ) 
            return false;
        
        if ($this->missingOldAndModel($name)) 
            return $checked;
        
        $posted = $this->getValueAttribute($name);
        return is_array($posted) ? in_array($value, $posted) : (bool)$posted;
    
    

当我在代码中时,我还看到 Laravel 内置了 in_array,前提是参数是一个数组。所以我在控制器中调用 View::make() 之前反序列化了$myModelInstance-&gt;AudienceGroups

【讨论】:

如果有人对这种 laravel 行为感兴趣,我已经为这个错误做出了贡献:github.com/laravel/framework/issues/5078 文档具有误导性,应进行调整。但是,您为什么认为这是错误? 我是 Laravel 的新手,但对我来说,让它像文档描述的那样起作用是有意义的,第三个参数能够覆盖模型数据,而不是像后备一样。跨度>

以上是关于如何在模型绑定中使用带有 Laravel 的复选框组的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel 表单模型绑定和复选框更新多对多 Eloquent 关系

使用 laravel 和 vue js 从 mysql 数据库中检查带有逗号分隔值的复选框

如何在 laravel 刀片模板中使用 JSON 数据进行模型绑定?

在 PHPUnit 中调用路由时如何在 Laravel 8 中模拟 Eloquent 模型

如何在Vue js中绑定带有芯片的复选框(双向绑定)

Laravel 5.0 路由模型绑定在销毁操作中不起作用