Supabase の update で 404 が出てテーブルに存在するデータを更新できなかった
"@supabase/supabase-js": "^1.24.0"`
SELECT, DELETE は動いた
const { data, error } = await supabase
.from('post_likes')
.select()
.match({ post_id: postId, account_id: accountId })
// console.log(data)
[
{
"postId": 1,
"accountId": 1,
"read": false
}
]
しかし、update が動かない
const { data, error } = await supabase
.from('post_likes')
.update({
read: true,
})
.match({ post_id: postId, account_id: accountId })
// console.log(data, error)
null []
PUT /rest/v1/post_likes?post_id=eq.1&account_id=eq.1
は 404 を返す
原因は RLS の policy の設定だった。
create policy "Users can update their own like."
on comment_likes for update with check ( auth.role() = 'authenticated' );
with check
を using
に変えたら動いた
create policy "Users can update their own like."
on comment_likes for update using ( auth.role() = 'authenticated' );
using
と with check
の違いは以下
using
任意のSQL条件式(戻り値はboolean)です。(省略) 行単位セキュリティが有効なときは、テーブルへの問い合わせにこの式が追加されます。 この式がtrueを返す行が可視となります。 この式がfalseまたはnullを返す行は、ユーザには(SELECTにおいて)不可視となり、また(UPDATEあるいはDELETEでは)更新の対象ではなくなります。 そのような行は静かに無視され、エラーは報告されません。
using が true を返す行が可視になる。
using が定義されていなかったので、先ほどはエラーメッセージもなく update ができなかったのだ。
with check
任意のSQL条件式(戻り値はboolean)です。 (省略) この式は、そのテーブルに対するINSERTおよびUPDATEの問い合わせで使用され、この式の評価がtrueになる行のみが許されます。 挿入されるレコード、あるいは更新の結果のレコードでこの式の評価がfalseまたはnullになるものについては、エラーが発生します。 check_expressionは元の内容ではなく、予定される更新の後の新しい内容に対して評価されることに注意してください。
with check が true を返す行が挿入・更新可能となる。
with check は INSERT
、UPDATE
で使用され、挿入・更新予定の内容を評価する。
つまり、新しい行のデータを使って条件文を組み立てられるということだ
出典
なお、UPDATE
に関しては以下のルールが適用される
USING句だけが指定されていた場合は、それがUSINGとWITH CHECKの両方に対して使用されます。