laravelとmysqlでJSON型のカラムを保存する時のバリデーションを3つ考えてみた
私はlaravel初心者です。一般的な方法などあれば教えていただけるとありがたいです
json型のfooカラムがあるテーブル
create table hoges (
`id` int unsigned not null primary key auto_increment,
`foo` json,
`created_at` datetime default null,
`updated_at` datetime default null
);
1. ミューテタとValidatorを使う
class Hoge extends Model
{
/**
* @var array
*/
protected $fillable = ['foo'];
/**
* @var array
*/
protected $casts = ['foo' => 'json'];
/**
* @param $value
*/
public function setFooAttribute($value)
{
$validator = Validator::make($value, [
'title' => 'required|max:30',
'body' => 'required',
]);
throw_if($validator->fails(), new \Exception("不正"));
$this->attributes['foo'] = json_encode($value);
}
}
class Hoge extends Model
{
/**
* @var array
*/
protected $fillable = ['foo'];
/**
* @var array
*/
protected $casts = ['foo' => 'json'];
/**
* @param $value
*/
public function setFooAttribute($value)
{
$validator = Validator::make($value, [
'title' => 'required|max:30',
'body' => 'required',
]);
throw_if($validator->fails(), new \Exception("不正"));
$this->attributes['foo'] = json_encode($value);
}
}
これで↓のように保存しようとしても、'body'
がないためエラーになってくれました
Hoge::create([
'foo' => ['title' => 'タイトル'],
]);
保存もできたのを確認できました
2. ミューテタとJSON Schemaを使う
# ググって上の方に出たライブラリを使いました
$ composer require justinrainbow/json-schema
# ググって上の方に出たライブラリを使いました
$ composer require justinrainbow/json-schema
あまり詳しくないですが、このような感じにしてみました
class Hoge extends Model
{
/**
* @var array
*/
protected $fillable = ['foo'];
/**
* @var array
*/
protected $casts = ['foo' => 'json'];
/**
* @param $value
*/
public function setFooAttribute($value)
{
$jsonSchema = <<<'JSON'
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"todo": {
"definitions": {
"id": {
"description": "TODOのID",
"type": "integer"
},
"naiyou": {
"description": "TODOの内容",
"type": "string"
}
}
}
},
"type": "object",
"properties": {
"todos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"$ref": "#/definitions/todo/definitions/id"
},
"naiyou": {
"$ref": "#/definitions/todo/definitions/naiyou"
}
}
}
}
}
}
JSON;
$jsonSchemaObject = json_decode($jsonSchema);
$validator = new \JsonSchema\Validator();
$validator->validate($value, $jsonSchemaObject);
throw_if(!$validator->isValid(), new \Exception("不正"));
$this->attributes['foo'] = json_encode([$value]);
}
}
Hoge::create([
'foo' => (object) [
'todos' => [
(object) ['id' => 1, 'naiyou' => '買い物'],
(object) ['id' => 2, 'naiyou' => '映画'],
],
],
]);
mysql8のcheck制約とJSON Schemaでバリデーションする
laravelを使わないで、mysqlの機能だけでやってみようと思います
(chekc制約は、mysql8.0.16から)
json_schema_validでtrueになったデータのみ入れられる
create table hoges (
`id` int unsigned not null primary key auto_increment,
`foo` json,
`created_at` datetime default null,
`updated_at` datetime default null,
check(
json_schema_valid(
'{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"todo": {
"definitions": {
"id": { "description": "TODOのID", "type": "integer"} ,
"naiyou": { "description": "TODOの内容", "type": "string" }
}
}
},
"type": "object",
"properties": {
"todos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "$ref": "#/definitions/todo/definitions/id" },
"naiyou": { "$ref": "#/definitions/todo/definitions/naiyou"}
}
}
}
}
}',
foo
)
)
);
-- OK
insert into hoges(foo) values('{"todos": [{"id": 1, "naiyou": "買い物"}, {"id": 2, "naiyou": "映画"}]}')
-- Error Code: 3819. Check constraint 'hoges_chk_1' is violated.
insert into hoges(foo) values('{"todos":1}');
みていただいてありがとうございましたm(_ _)m
Author And Source
この問題について(laravelとmysqlでJSON型のカラムを保存する時のバリデーションを3つ考えてみた), 我々は、より多くの情報をここで見つけました https://qiita.com/okumurakengo/items/75b3011f51ce342a26eb著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .