🫠
【備忘録】laravel-dynamodbのpaginate()で詰まった話
概要
laravel-dynamodbとは、LaravelでDynamoDBを操作できるライブラリです。
今回はライブラリの機能であるpaginate()
で詰まった話をします。
何があったのか
App\Models\Post.php
protected $casts = [
'is_opened' => Opened::class,
'opened_at' => 'datetime',
'closed_at' => 'datetime',
];
protected $dynamoDbIndexKeys = [
'opened_index' => [
'hash' => 'is_opened',
'range' => 'opened_at',
],
];
Post内で上記キャストやGSIを設定した状態で、
// ページの最後の項目を取得する
$nextPage = $query->afterKey($items->lastKey())->limit(2)->all();
上記を試したところ、Type mismatch for attribute to update
とエラーが発生しました。
原因は?
afterKey()
にある
marshalItem()
で使っている
marshalValue()
にて(長いので頭のみ)、$type
の型がEnum
とCarbon
のせいかうまくいっておらず、インデックスを設定したキーであるis_opened
とopened_at
がNULL
になっていた。
つまり、内部でDynamoDb::marshalItem($key)
を使っているメソッドでEnum
やCarbon
にキャストしてるキーがあると正常に取得できない......。
どうやって解決したのか?
諸事情により少し省略しますが......
// 現在表示している最後の記事を取得
$lastPost = Post::findOrFail($lastId);
// 次のデータを取得
$items = $query->afterKey([
'id' => $lastPost->id,
'is_opened' => $lastPost->is_opened->value,
'opened_at' => $lastPost->opened_at->format('Y-m-d H:i:s'),
])
->limit($incrementedNum)
->all();
と、afterKey()
に渡すキーを文字列で取得するよう修正しました。
いや〜〜〜調査に時間が掛かりました......。
Discussion