Rails+Vue.jsでユーザー登録機能を作る

#Rails6.0+Vue.jsでユーザー登録の機能を作る

RailsとVue.jsを使用したSPAの新規登録機能を作成したため、
自分用にメモ書き。

まずはフロント側のVue.jsを作成

共通部分のソースコード

```vue:app/javascript/app.vue
<template>
  <div>
    <router-view></router-view>
  </div>
</template>

<script>
import Vue from 'vue'
import VueRouter from 'vue-router'

// User(ユーザー)
import UserNewPage from 'user/UserNewPage.vue'

const router = new VueRouter({
  routes: [
    // User(ユーザー)
    { path: '/users/new',
      name: 'UserNewPage',
      component: UserNewPage    },
    ]
})


// ref. https://jp.vuejs.org/v2/guide/plugins.html#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%AE%E4%BD%BF%E7%94%A8
Vue.use(VueRouter)

export default {
  router
}
</script>

<style scoped>
</style>

```

新規登録画面のソースコード

```vue:app/javascript/user/UserNewPage.vue
<template>
  <div>
    <user-form-pane :errors="errors" :user="user" @submit="createUser"></user-form-pane>
  </div>
</template>

<script>
import axios from 'axios';

import UserFormPane from 'user/UserFormPane.vue';

export default {
  components: {
    UserFormPane
  },
  data() {
    return {
      user: {
        name: '',
        email: '',
        password: '',
        password_confirmation: ''
      },
      errors: ''
    }
  },
  methods: {
    createUser: function() {
      console.log("動いた")
      console.log(this.user.password)
      axios
        .post('/api/v1/users', this.user)
        .then(response => {
          let u = response.data;
          this.$router.push({ name: 'UserDetailPage', params: { id: u.id } });
        })
        .catch(error => {
          console.error(error);
          if (error.response.data && error.response.data.errors) {
            this.errors = error.response.data.errors;
          }
        });
    }
  }
}
</script>

<style scoped>
</style>
```

UserNewPage.vueで呼び出されているUserFormPaneのソース

```vue:app/javascript/user/UserFormPane.vue
<template>
  <form @submit.prevent="$emit('submit')">
    <div v-if="errors.length != 0">
      <ul v-for="e in errors" :key="e">
        <li><font color="red">{{ e }}</font></li>
      </ul>
    </div>
    <div>
      <label>Name</label>
      <input v-model="user.name" type="text">
    </div>
    <div>
      <label>Email</label>
      <input v-model="user.email" type="text">
    </div>
    <div>
      <label>Password</label>
      <input v-model="user.password" type="password">
    </div>
    <div>
      <label>Password(Confirmation)</label>
      <input v-model="user.password_confirmation" type="password">
    </div>
    <button type="submit">Commit</button>
  </form>
</template>

<script>
export default {
  props: {
    user: {},
    errors: ''
  }
}
</script>

<style>
</style>
```

次にRails側でテーブルとモデルを作成する
以下のコマンドをターミナルで実行

```
$ rails g model User name:string email:string password_digest:string
$ rails db:migrate
```

API側のコントローラークラスを以下の記述を追加

```Ruby:app/controllers/api/v1/users_controller.rb
def create
    user = User.new(user_params)
    if user.save
      render json: user, status: :created
    else
      render json: { errors: user.errors.full_messages }, status: :unprocessable_entity
    end
end


private
    def user_params
        params.permit(:name, :email, :password, :password_confirmation)
    end
```

モデルクラスに以下を追加

```ruby:app/models/user.rb
class User < ApplicationRecord
  has_secure_password
end
```

ルート設定を追加

```ruby:config/routes.rb
resources :users, only: [:create]
```

上記の設定を行えば、新規登録機能を作成できる