🙌

[2回目]Typescript+RailsでAPIをつくって表示させるまで

2021/03/29に公開

今回すること

Rails API でログイン周りの構築をしていく。
前回と同じでこちらの動画を参考に構築していきます。

モデル作成

ファイル構成はこんな感じです。

controller
 ├─ api
 │  └─ v1
 │	└─ users_controller.rb
 └─ site_controller.rb

モデルを作っていきます。パスワードを暗号化しておきます。

rails g model user username:string email:string password_digest:string 

userモデルに以下を記述します。記述することによりusersテーブルにパスワードを保存するとき、パスワードを暗号化して保存してくれます。見入力、一意性などのバリデーションも追加しておく。

user.rb
class User < ApplicationRecord
    has_secure_password
    validates_presence_of :email, :username, :password
    validates_uniqueness_of :email
    validates :username, uniqueness: { case_sensitive: true }
end

gem 'bcrypt', '~> 3.1.7'のコメントアウトを外してbundle installします。
適当にユーザーを作ります。

seeds.rb
User.create(username: 'test1',email: 'test1@gmail.com',password: 'aaaaa')
User.create(name: 'test2', email: 'test2@kmail.com', password: 'bbbbb')
User.create(name: 'test3', email: 'test3@kmail.com', password: 'ccccc')

user_controller.rbにindexアクションを追加します.

user_controller.rb
class Api::V1::UsersController < ApplicationController
    def index
        users = User.order(created_at: desc)
        render json: {status: 'success',data: users}
    end
end

route.rbでルーティングを追加します

namespace :api do
    namespace :v1 do
      resources :users
    end
end

これでAPIをたたくをUser情報ががえってきます
Postman
passwordが暗号化されていることがわかります。今回はindexアクションのみにします。

Reactでhttp通信してみる。

axiosを使って通信してきます。
ファイルを少し追加したので記載しておきます。

 component
 ├─Auth
 │ └─Signup.tsx
 └─ map.tsx

axiosでapiを叩いてテータを取得します。得たデータをmapで表示していきます。

Signup.tsx
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from "axios";

interface User {
  username: string;
  email: string;
  password: string;
}

function Signup() {
  const [users, setUsers] = useState<User[]>([]);
  const getAllUsers = () => {
    axios
      .get("/api/v1/users.json")
      .then((res) => {
        console.log(res.data);
        setUsers(res.data);
      })
      .catch((e) => {
        console.log(e);
      });
  };
  useEffect(() => {
    getAllUsers();
  }, []);
  return (
    <div>
      {users.map((user, index) => {
        return (
          <div key={index}>
            {user.username}
            {user.email}
          </div>
        );
      })}
      <Link to="/map">map</Link>
    </div>
  );
}

export default Signup;

期待通りに表示できました!
Imgur

@今書いているソースコードです

さいごに

次回はuser登録、ログイン、ログアウト等の機能も追加していきます。
map表示だけてなくTwitterのような投稿機能もセットで考えていきます。
自分が書いているコードや考え方がおかしかった場合はコメント等で教えてもらえると嬉しいです。

Discussion