我有一个简单的MySQL数据库表,如下所示:
mysql> show create table provenance;
| provenance | CREATE TABLE `provenance` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Unique incremental id',
`name` char(255) NOT NULL DEFAULT 'AUTO-ADDED',
`instance` char(255) NOT NULL,
`username` char(255) DEFAULT NULL COMMENT 'User name',
`priority` int(11) NOT NULL DEFAULT '0' COMMENT 'Provenance priority',
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=2869 DEFAULT CHARSET=latin1 COMMENT='Provenance' |
mysql>
如您所见,存在具有 DEFAULT 值的字段:name
和priority
。
Laravel 模型类似于:
class ProvenanceModel extends Model
{
protected $table = 'provenance';
protected $fillable = [
'name',
'instance',
'username',
'priority'
];
}
和控制器:
class ProvenanceController extends Controller
{
public function myStore($array)
{
return ProvenanceModel::firstOrCreate(
[
'name' => $array['name'],
'instance' => $array['instance'],
'username' => $array['username'],
'priority' => $array['priority'],
]
);
}
}
问题是输入$array[]
不能包含name
或priority
(它们是通过 DEFAULT 从数据库中设置的)。
但是如何更改代码以避免错误,例如,$array['name']
不存在?
一个想法可能是将 Controller 代码更改为:
class ProvenanceController extends Controller
{
public function myStore($array)
{
return ProvenanceModel::firstOrCreate(
[
'name' => $array['name'] ?? 'AUTO-ADDED',
'instance' => $array['instance'],
'username' => $array['username'],
'priority' => $array['priority'] ?? 0,
]
);
}
}
但是如果我更改数据库上的 DEFAULT ,我需要更改PHP代码,我不喜欢这样。
如果未传递该字段,是否可以使用 DEFAULT 数据库值?
谢谢。
答案 0 :(得分:0)
Laravel无法在构造查询时知道数据库的默认值。
您最好的选择是将firstOrCreate
分为2个通话:
$model = ProvenanceModel::where($attributes)->first();
if (is_null($model)) {
$model = ProvenanceModel::create([
...
// non-default attributes
...
]);
}
return $model;
答案 1 :(得分:0)
在@prgrm注释之后,解决方案是仅将输入中接收到的字段插入ProvenanceModel::create()
方法中。
例如:
class ProvenanceController extends Controller
{
public function myStore($array)
{
isset($array['name']) ? $secondArray['name'] = $array['name'] : null;
isset($array['instance']) ? $secondArray['instance'] = $array['instance'] : null;
isset($array['username']) ? $secondArray['username'] = $array['username'] : null;
isset($array['priority']) ? $secondArray['priority'] = $array['priority'] : null;
return ProvenanceModel::firstOrCreate($secondArray);
}
}
然后,如果未设置$array['name']
,则$secondArray
将为:
$secondArray[
'instance' => '<value>'
'username' => '<value>'
'priority' => '<value>'
]
,并且name
字段将填充 DEFAULT MySQL值'AUTO-ADDED'
。
要使所有内容合而为一而不建立$secondArray()
:
class ProvenanceController extends Controller
{
public function myStore($array)
{
return ProvenanceModel::firstOrCreate(
[
isset($array['name']) ? 'name' : 'xx' => $array['name'] ?? null,
isset($array['instance']) ? 'instance' : 'xx' => $array['instance'] ?? null,
isset($array['username']) ? 'username' : 'xx' => $array['username'] ?? null,
isset($array['priority']) ? 'priority' : 'xx' => $array['priority'] ?? null,
]
);
}
}
然后,如果未设置$array['name']
,它将是:
return ProvenanceModel::firstOrCreate(
[
'xx' => null,
'instance' => <value>,
'username' => <value>,
'priority' => <value>,
]
);
xx
字段不在$fillable
数组中,将不会在INSERT
语句中使用。