←Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #5 ログイン・ログアウトの実装
はじめに
今回はNuxt編の最終回。
記事投稿フォームをindexに設置します。
ログインしていないと書き込めないので、ログイン中のみフォームを表示します。
Railsのレスポンスコード修正
まず下準備として、Rails側の修正漏れ箇所を直します。
postのsave失敗時、ステータスが200(正常)で返ってきてしまっておりエラーがキャッチできないので、レスポンスコードを422で返すようにします。
...
if post.save
render json: post
else
- render json: { errors: post.errors }
+ render json: { errors: post.errors }, status: 422
end
end
...
if @post.update(post_params)
render json: @post
else
- render json: { errors: @post.errors }
+ render json: { errors: @post.errors }, status: 422
end
end
...
postした時にNuxt側でtry catchを使っていますが、エラーが出てもレスポンスコードが200だとcatchブロックに行きません。ここは以前の設定ミスなのであらかじめ塞いでおきます。
pages/index.vueとstore/index.jsの修正
sm8
md6
>
+ <form v-if="logged_in" @submit.prevent="newPost">
+ <v-card>
+ <v-card-title class="headline">
+ 新規投稿
+ </v-card-title>
+ <v-card-text>
+ <ul v-if="errors">
+ <li v-for="(message, key) in errors" :key="key">
+ {{ key }}
+ <span v-for="(m, i) in message" :key="i">
+ {{ m }}
+ </span>
+ </li>
+ </ul>
+ <v-text-field
+ id="subject"
+ v-model="subject"
+ label="subject"
+ name="subject"
+ prepend-icon="mdi-subtitles"
+ />
+ <v-textarea
+ id="body"
+ v-model="body"
+ label="body"
+ name="body"
+ prepend-icon="mdi-comment-text"
+ />
+ </v-card-text>
+ <v-card-actions>
+ <v-spacer />
+ <v-btn color="primary" type="submit">
+ 投稿
+ </v-btn>
+ </v-card-actions>
+ </v-card>
+ </form>
<v-card v-for="post in posts" :key="post.id">
<v-card-title class="headline">
<n-link :to="`/posts/${post.id}`">
...
<script>
export default {
+ data () {
+ return {
+ subject: '',
+ body: '',
+ errors: []
+ }
+ },
computed: {
posts () {
return this.$store.getters['posts/posts']
+ },
+ logged_in () {
+ return this.$store.getters.logged_in
+ }
+ },
+ methods: {
+ async newPost () {
+ try {
+ await this.$store.dispatch('posts/newPost', {
+ subject: this.subject,
+ body: this.body
+ })
+ this.subject = ''
+ this.body = ''
+ this.errors = []
+ } catch (e) {
+ this.errors = e.data.errors
+ }
+ const posts = await this.$store.dispatch('posts/fetchPosts')
+ this.$store.commit('posts/setPosts', posts.posts)
}
}
}
エラーメッセージの表示箇所や、投稿後のposts再取得あたりがやっつけ感満載ですが。
やっていることはログインフォーム等と大差無いですね。
最後にstore/posts.jsにnewPostを定義して終わりです。
export const actions = {
async fetchPosts () {
return await this.$axios.$get('/v1/posts')
+ },
+ async newPost (_c, post) {
+ return await this.$axios.$post('/v1/posts', post)
}
}
終わりに
今回でNuxt.js編最終回です。
Rails編からご覧いただいていた場合、18+6で24章にも及ぶ連載です。ご覧いただいたり、プログラムを書いていただいた皆様ありがとうございました。
Railsで実装したCRUD処理でNuxt側未実装の点も多いため、ここからは自力で実装に挑戦してみてください。
また、RailsもNuxtも(特にNuxtは)初心者でお見苦しいコードも多々あったかと思いますが、これをきっかけにオリジナルのアプリケーション構築への挑戦をオススメします。
終わり
【連載目次へ】