1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React×TypeScript×Supabase】supabaseでテーブルを紐づけた際にデータ挿入で迷った話

Last updated at Posted at 2025-03-07

はじめに

supabaseで、リレーションしているテーブルにIDを紐づける時、
少し手法に迷ったので記事にします

テーブルの状況

現在のテーブル状況はこちら
userテーブル

カラム名
id string
email string
name string
created_at string
user_id string
reviews_id string
record_id string
goals_id string

goalsテーブル

カラム名
id string
target_records string
current_records string
target_sales_hours string
current_sales_hours string
week_start_date string

idとgoals_idを紐づけています

問題

SQLを使う?とか考えていたりして、とにかくやり方に迷いました。

一旦、作業をバラバラにして考えてみたところ、大雑把に三つのやり方に分けられるのかなと。

1.goalsテーブルに挿入する
2.goalsテーブルのidを取得する
3.それを現在ログインしているuserのテーブルに挿入する

こんな感じで考えました。(もっといい手法があったらすみません)

解決方法

まずは2つのapiを作成します

// insertをしてデータを挿入
export const InsertGoal = async (goal: GoalTargetData) => {
  const { data, error } = await supabase.from("goals").insert(goal).select("id").single();
  if (error) {
    throw error;
  }
  return data.id;
};

//user_idに挿入するためのAPI
export const UpdateUserGoalId = async (userId: string, goalId: string) => {
  const { error } = await supabase.from("users").update({ goals_id: goalId }).eq("id", userId);
  if (error) {
    throw error;
  }
};

onClickとかでデータを送るときのコードを準備

const [user] = useAtom(userAtom);
  const [learning, setLearning] = useState<number>(0);
  const [sales, setSales] = useState<number>(0);
  const [works, setWorks] = useState<number>(0);
  const [error, setError] = useState<string>("");
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    try {
      setIsLoading(true);
      // NOTE: データの整形をここで行う
      const goal = {
        target_records_hours: learning,
        target_sales_hours: sales,
        target_works_hours: works,
      };
      const goalId = await InsertGoal(goal);
      if (user?.id) {
        await UpdateUserGoalId(user.id, goalId);
      }
    } catch (error) {
      if (error instanceof Error) {
        console.log(error);
        setError(error.message);
      } else {
        setError("エラーが発生しました");
      }
    } finally {
      setIsLoading(false);
    }
  };

今回は状況切り分けのために、tryを使ってconsole上でエラーハンドリングをしましたが、ここはちゃんとしたコードを書いた方がいいと思います

まず、さっきのやり方で考えると、

    const goalId = await InsertGoal(goal);
      if (user?.id) {
        await UpdateUserGoalId(user.id, goalId);
      }

InsertGoalreturndata.idを返しているので、
それを一旦、変数で格納します
その後、UpdateUserGoalId()を使用します
api側で決めた引数としては、
第一引数が、userIdで、第二引数が、goalIdです

そして、今回はjotaiで管理していたuserつまり、今回ログインしているユーザーの情報を、atomで引っ張ってきます

const [user] = useAtom(userAtom);

そこでuser.idを設定してあげると、今ログインしているユーザーのIDにあるカラムのgoals_idに入るってわけですね。

おわりに

手法に迷うことはありますが、迷ったり詰まったら一度作業をバラバラにして考えてみる。これを徹底していこうと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?