はじめに
dynamodbに空白の値が保存されないテストを走らせた際に詰まってしまったので簡単にまとめてみます
状況
dynamoidのupdateメソッドを呼び出すとエラーをキャッチできず、200を返してしまう
原因
dynamoidのupdateメソッドは以下の場合において、レコードが自動的に削除されるため例外が発生しないようです
- 属性が存在しない
- 値がnilの場合
解決方法
update処理を実行する前に、受け取ったパラメータに空白が含まれるかのチェックを行ってエラーハンドリングする
テスト対象
require 'rails_helper'
RSpec.describe "Hoges", type: :request, dynamodb: true do
let(:update_param) {{
title: updated_title,
comments: ['test_comment1', 'test_comment2']
}}
let(:hoge_id) { Hoge.first.id }
describe "PATCH /update" do
let(:updated_title) { 'updated_title' }
subject(:result) { patch hoge_path(id: hoge_id, hoge: update_param) }
略
context '不正なパラメータのとき' do
let(:updated_title) { '' }
let(:hoge_id) { Hoge.last.id }
it 'アクセスできないこと' do
create(:hoge)
expect(result).to eq 400
end
end
end
end
メソッド(修正前)
backend/app/models/hoge.rb
def self.update_hoge(hoge_id, hoge_value)
hoge = Hoge.update(hoge_id, hoge_value)
{ status: 200, value: hoge }
rescue StandardError, Aws::DynamoDB::Errors::ServiceError => e
{ status: 500, value: e.message }
end
メソッド(修正後)
backend/app/models/hoge.rb
def self.update_hoge(hoge_id, hoge_value)
# 修正箇所
return { status: 400, value: "can't be blank" } if hoge_value.to_h.any? { |_key, value| value.blank? }
hoge = Hoge.update(hoge_id, hoge_value)
{ status: 200, value: hoge }
rescue StandardError, Aws::DynamoDB::Errors::ServiceError => e
{ status: 500, value: e.message }
end
おわりに
dynamoidの公式では言及されていないようだったので原因に気づくまでに時間がかかってしまいました。
dynamoidのupdateメソッドでAWS SDKのDynamoDB::Client#update_itemメソッドを呼び出していて、updateに成功した場合はオブジェクトを返し、失敗した場合は例外を返さない仕様のようです。