【问题标题】:Putting boolean values in the Model $fillable property is prevent them from working将布尔值放在 Model $fillable 属性中会阻止它们工作
【发布时间】:2022-01-01 08:55:47
【问题描述】:

运行一些测试,但在模型的某些布尔输入上一直失败。我基本上会运行一个测试,将一个实体提交到数据库,然后将其拉出并确保它们匹配。

当我将布尔值放入模型的 $fillable 属性时,布尔值不断失败。据我了解,您需要将所有预期的输入放在那里。这些布尔属性来自复选框输入。

class Contract extends Model {
use HasFactory;

protected $table = 'contracts';
protected $guarded = ['id'];

protected $casts = [
    'is_volunteer' => 'boolean',
    'tpp_accepted' => 'boolean',
    'is_old_law' => 'boolean'
];

protected $fillable = [     
    //'is_volunteer',       
    //'is_old_law',     
    //'tpp_accepted',
    'created_by_user',
    'client_db_id',
    ...

/*
 *  Turn a check box value into a bool
 */
protected function checkBoxToBoolean($value): bool {
    return ( !!$value ) ? true : false;
}

一个复选框的修改器/访问器示例

    public function getTppAcceptedAttribute($value): bool { 
        return (bool) $value;
    }


    public function setTppAcceptedAttribute($value) {   
         $this->attributes['tpp_accepted'] = $this->checkBoxToBoolean($value);
    }

数据库蓝图 ...

class CreateContractsTable extends Migration {

    public function up() {
        Schema::create('contracts', function (Blueprint $table) {
        $table->id();
        $table->timestamps();           
        $table->unsignedBigInteger('created_by_user')->nullable();          
        $table->boolean('is_volunteer')->default(false);
        $table->boolean('is_old_law')->default(false);          
        $table->boolean('tpp_accepted')->default(false);
        ...

我用来检查现有模型和数组之间哪些值不同的辅助方法。

/*
 *  Return changed values
 */
public function getDiff(array $compare): array {
    
    $compareModel = self::make($compare);       
    
    $diff = array_diff_assoc($compareModel->attributes, $this->attributes);
    
    foreach(self::getNonInputKeys() as $k) 
        unset($diff[$k]);           
        
    return $diff;
}

我在这里缺少的是将布尔输入放入 $fillable 属性错误/不正确的做法。为什么省略它们时它会起作用。一切正常,除了布尔值哈哈。

【问题讨论】:

  • 失败怎么办?您在这里没有显示与使用属性填充模型相关的任何内容......还有为什么您有一个修改器和一个正在转换的属性的访问器? ...您的 checkBoxToBoolean 方法正在这样做:bool ? true : false 这是多余的,顺便说一句
  • 他们总是从模型中出来。我已经得到了 mutators 和 accessors 是一个快点工作该死的解决方案。
  • 您没有向我们展示如何使用属性或使用这些属性创建模型实例,所有这些布尔值的默认值是 false 所以也许您没有将任何这些属性传递给数据库

标签: laravel eloquent


【解决方案1】:

所以我对问题进行了三角剖分。这是我从“通过 Laravel 模型设置和获取布尔值”兔子洞的发现。

1 - 设置 bool 值时,除非我使用 mutator 将其转换为 0 或 1 int,否则它将不起作用,不是 bool。我相信在数据库中,布尔值只是一个 TINTINT(1) 值,这可能是需要 0 或 1 的原因。

protected function checkBoxToBoolean($value) {
    return ( (bool) $value ) ? 1 : 0;    
}

public function setClientActiveAttribute($value) {
    $this->attributes['client_active'] = $this->checkBoxToBoolean($value);
}   

2 - 是的,如果您使用质量对齐(我相信大多数人都是),请确保您的 bool 键位于模型的 $fillable 数组属性中。

protected $fillable = [
    'client_id',
    'client_active' <- ...

3 - 将您的布尔键添加到模型的 $casts 属性中

protected $casts = [
    'client_active' => 'boolean'
];

4 - 模型值以您声明它们的方式访问。不像骆驼案!这是我搞砸的地方

$myBoolValue = $model->client_active

不是

$myBoolValue = $model->clientActive

我是 Laravel 的新手,大多数东西都是从骆驼案来回转换的,所以这对我来说是一个陷阱。我希望这可以帮助其他人节省几个小时。

【讨论】:

  • $casts 属性的全部意义在于自动进行强制转换,您不需要使用 mutators。始终按定义访问数据库列。如果您提供了问题 cmets 中要求的调试信息,那么您可能会被指出一个更有成效的方向。
  • 如果我删除 mutator,我的测试会失败,因为只返回 false。我正在使用质量对齐设置模型
猜你喜欢
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多