「ユーザーが作成されたらテーブルに追加」といった、条件で自動発動するトリガー処理を記載していきます。

トリガー処理に必要なもの

Supabaseでのトリガー処理は、下記の2点を作成する必要があります

  1. トリガー時に起動する関数の作成
  2. トリガーの作成

なお、これらの知識はSupabaseでは無くPostgreSQLの知識である事も多いので、解らない時はPostgreSQLのトリガー処理で調べるのも良いかも知れません。

参考リンク

今回は下記のページも参考にさせていただきました。

トリガ・トリガプロシージャの使い方(PostgreSQL)

SupaBase公式のトリガー処理コード

テーブルの作成

テンプレートで作ったprofileに追加しようとした所、上手く行かないので新規で作成します。

UUID・email・自由テキスト領域を持った新規テーブルをSQLエディターで下記のように作成します。

create table users (
  id uuid references auth.users not null primary key,
  email text,
  detail text
);

usersテーブルが生成されます。

トリガーで呼ばれる関数を作成

トリガーで呼ばれるストアドファンクションを作成します。SQLエディターで次のようなコードを記述し実行します。

create or replace function public.handle_new_user() 
returns trigger as 
$$
begin
  insert into public.users (id, email, detail)
  values (new.id, new.email, '未入力です');
  return new;
end;
$$ 
language plpgsql security definer;

解説

ストアドファンクションの解説をします。

【1】 create or replace function public.handle_new_user() 
【2】 returns trigger as $$
【3】 begin
【4】   insert into public.users (id, email, detail)
【5】   values (new.id, new.email, '未入力です');
【6】   return new;
【7】 end;
【8】 $$ language plpgsql security definer;
  • 【2】…triggerを返しています。
  • 【4】…usersテーブルのid,email,detail列に入れる宣言です。
  • 【5】…入れる値の設定です。このnewの部分には、今回は生成されたユーザーのAuthが入ります(※1)。(次項のトリガーで関連づけてる?)new.idでAuth.id、new.emailはAuth.emailを指します。detailに対してだけ、直値の「未入力です」を入れています。
  • 【6】…そのnewを返しています。
  • 【7】…言語設定の後にセキュリティ設定も加えています。「security definer」は関数定義者のみが実行できるという意味です(参考記事

※1…トリガでの INSERT/UPDATE 操作によって更新されたデータベースの行、が仕様みたいです。

トリガーを作成

最後にトリガー自体をSQLエディターで作成します。

create trigger on_auth_user_created
  after insert on auth.users for each row
  execute procedure public.handle_new_user();

解説

書式はこちらのページの記事も参考にさせていただきました。

トリガ・トリガプロシージャの使い方(PostgreSQL)

【1】 create trigger on_auth_user_created
【2】   after insert on auth.users for each row
【3】   execute procedure public.handle_new_user();
  • 【1】…トリガー作成の宣言です。on_auth_user_createdという名前になります。
  • 【2】…auth.usersのinsert、ユーザーの追加が行われた後に実行する定義です。
  • 【3】…public.handle_new_user(先ほど作ったhandle_new_user関数)を呼びます。

実行

ユーザーを作成するとusersテーブルに追加されている事が確認出来ます。

(おまけ)updateをトリガーにして更新

先ほどはユーザーの追加で行を追加していました。今回はテーブルの更新をトリガーに、別のテーブルを更新してみます。

注意:自分自身のアップデートをトリガーにして、自分自身をupdate句を使った更新をすると無限ループになるので十分に注意してください。

クエリエディタで作成

下記をまるっとクエリエディタにコピーして実行します。

--ダミーテーブル作成ここから
CREATE TABLE public.update_test_table_01 (
    id int PRIMARY KEY,
    text_test1 text,
    number_test1 int
);

CREATE TABLE public.update_test_table_02 (
    id int PRIMARY KEY,
    text_test2 text,
    number_test2 int
);

INSERT INTO public.update_test_table_01
(id,text_test1, number_test1)
VALUES
(1,'テスト1番', 100),
(2,'テスト弐番', 250),
(3,'テストさん番', 500);


INSERT INTO public.update_test_table_02
(id,text_test2, number_test2)
VALUES
(1,'', 0),
(2,'', 0),
(3,'', 0);
--ダミーテーブル作成ここまで


create or replace function public.table_copy() 
returns trigger as $$
begin
  UPDATE public.update_test_table_02 
  set
   text_test2 = new.text_test1,
   number_test2 = new.number_test1
  WHERE id = new.id;
  return new;
end;
$$ language plpgsql security definer;


create trigger on_table_update_test
  after update on public.update_test_table_01
  for each row execute procedure public.table_copy();

解説

ダミーテーブルを2つ作ってデータを入れた後に、関数とトリガーを作ってます。

下記はトリガーが実行された時に呼ばれる関数です。newにはupdate_test_table_01が来ており、それぞれの値をupdate_test_table_02の各項目に入れています。

create or replace function public.table_copy() 
returns trigger as $$
begin
  UPDATE public.update_test_table_02 
  set
   text_test2 = new.text_test1,
   number_test2 = new.number_test1
  WHERE id = new.id;
  return new;
end;
$$ language plpgsql security definer;

一方、トリガーはこちらになります。update_test_table_01がupdateされたらpublic.table_copyを呼ぶ、というトリガーになります。

create trigger on_table_update_test
  after update on public.update_test_table_01
  for each row execute procedure public.table_copy();

注意:自分自身のアップデートをトリガーにして、自分自身をupdate句を使った更新をすると無限ループになるので十分に注意してください。

次のページはこちら