Open6

Supabase の Tips

プログラミングをするパンダプログラミングをするパンダ

RLS を設定していないテーブルを操作しようとするとエラーは出ない。

例: posts テーブルに delete の policy を設定せず、JSで delete を実行した時の結果は以下

const {data, error} = await supabase.from('posts').delete().match({ id: postId })

console.log(data, error) // [], null

設定を忘れることがあると思うので注意

プログラミングをするパンダプログラミングをするパンダ

全てのテーブルに user_id を入れるのではなく、accounts テーブルを作ってそこの ID と紐づけていけばいいんじゃないかと思う

create policy "Users can update their own post."
  on posts for update with check (
  -- auth.uid() が、 accounts テーブルの user_id と一致したら、投稿を更新できる      
  exists (
    select 1 from posts
      where auth.uid() = (
      select user_id from accounts where accounts.id = posts.account_id
    )
  )
);

こうやって書くと、

create policy "Users can update their own comments."
  on comments for update using ( auth.uid() = user_id );

こんなことしなくていい。つまり、user_id を posts テーブルに持たなくて済む

プログラミングをするパンダプログラミングをするパンダ

select 1 は boolean を返す。レコードがあれば true。
ここは Row Level Security の policy なのでレコードを返さなくても boolean を返せば ok

user_id を持たせたくないテーブルには上記のように対応していけば良い

プログラミングをするパンダプログラミングをするパンダ

auth.user にユーザー作成の新規行が作成されたとき、accounts テーブル にも新規データを作成する

create function public.handle_new_user_to_accounts()
    returns trigger
    language plpgsql
security definer
as $$
begin
insert into public.accounts (user_id)
values (new.id);
return new;
end;
$$;

-- trigger は function に依存している
create trigger on_auth_user_created
    after insert on auth.users
    for each row execute procedure public.handle_new_user_to_accounts();

https://supabase.io/docs/guides/auth/managing-user-data#advanced-techniques