前回の記事まででコンテンツ一覧、詳細表示、コンテンツ新規作成まで実装できたので、今回の記事はコンテンツの編集、削除の機能を実装していきます。
前回の記事はこちら:
Rails + Nuxt CRUDアプリ作成(新規登録、詳細表示編)
1.編集画面作成(Nuxt)
まず、詳細画面の「Topへ」のボタンの横に「編集」ボタンを設置し、それをクリックすると新規作成時と同じような投稿フォームがモーダル で表示されるように実装します。
front/pages/posts/_id.vue
...省略
Topへ
</b-button>
<b-button
size="sm"
variant="success"
@click="openModal()"
>
編集
</b-button>
</b-card>
<b-modal
hide-header
hide-footer
id="edit-modal"
>
<b-form-textarea
v-model="content"
>
</b-form-textarea>
<b-button
class="mt-3"
variant="primary"
:disabled="disabled"
@click="update()"
>
更新
</b-button>
</b-modal>
<script>
export default {
data: () => {
return {
content: '',
post: {},
}
},
methods: {
...省略
openModal() {
this.content = this.post.content
this.$bvModal.show('edit-modal')
},
modalの使い方はこちら
https://bootstrap-vue.org/docs/components/modal#modals
これで編集ボタンをクリックするとモーダル が開きtextareaにcontentのデータが入っていると思います。

axios通信: 送信(Nuxt)
次は「更新」ボタンをクリックした時にrailsのupdateメソッドが実行されるように実装していきます。
front/pages/posts/_id.vue
...省略
computed: {
params() {
return {
post: {
content: this.content
}
}
},
}
methods: {
update() {
const url = `/api/v1/posts/${this.$route.params.id}`
this.$axios.put(url, this.params)
.then((res) => {
// 成功時の処理
})
.catch((err) => {
// 失敗時の処理
})
},
これで更新ボタンを押した時にaxios通信でRails側のupdateアクションを実行するようになりました。次はRails側のupdateアクションを実装していきます。
updateアクション実装(Rails)
前回実装したcreateアクションと同様にupdateアクションを実装していきます。
流れは
- ルーティングの生成
- コントローラのupdateアクション実装
です。
- ルーティングの生成
api/config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :hello, only: [:index]
resources :posts, only: [:index, :create, :show, :update]
end
end
end
- コントローラのupdateアクション実装
api/app/controllers/api/v1/posts_controller.rb
def update
post = Post.find_by(id: params[:id])
if post.update(content: params[:post][:content])
render json: '更新に成功しました', status: 200
else
render json: '更新に失敗しました', status: 500
end
end
これでRails側の実装は完了しました。次はNuxt側のレスポンスを実装します。
axios通信: レスポンス(Nuxt)
thenとcatchのなかの処理を加えていきます。
front/pages/posts/_id.vue
update() {
const url = `/api/v1/posts/${this.$route.params.id}`
this.$axios.put(url, this.params)
.then((res) => {
// 成功時の処理
this.$bvModal.hide('edit-modal')
this.fetchContent()
this.$bvToast.toast(res.data, {
title: '成功',
variant: 'success'
})
})
.catch((err) => {
// 失敗時の処理
const message = err.response.data
this.$bvToast.toast(message, {
title: 'エラー',
variant: 'danger'
})
})
},

これでコンテンツの編集機能が実装できました。
削除ボタン実装(Nuxt)
最後に削除機能を実装していきます。
手順は更新と同じように実装します。
front/pages/posts/_id.vue
...省略
編集
</b-button>
<b-button
v-b-modal.confirm-delete
size="sm"
variant="danger"
>
削除
</b-button>
...省略
<b-modal
id="confirm-delete"
hide-header
@ok="destroy()"
>
<p>投稿を削除しますか?</p>
</b-modal>
</div>
</template>
これで編集の横に削除ボタンが表示されクリックすると削除確認のモーダル が表示されます。

axios通信: 送信(Nuxt)
次は削除モーダル を押した時にdestroyアクションが実行されるように実装していきます。
front/pages/posts/_id.vue
<script>
export default {
...省略
methods: {
... 省略
destroy() {
const url = `/api/v1/posts/${this.$route.params.id}`
this.$axios.delete(url)
.then(() => {
this.toTop()
})
.catch((err) => {
const message = err.response.data
this.$bvToast.toast(message, {
title: 'エラー',
variant: 'danger'
})
})
}
}
}
これで削除に成功したらトップページに戻ルようになりました。
最後にRails側のdestroyアクションを実装します。
destroyアクション実装(Rails)
これまでと同じように
- ルーティング生成
- destroyアクション実装
の手順で進めます。
- ルーティング生成
api/config/routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :hello, only: [:index]
resources :posts, only: [:index, :create, :show, :update, :destroy]
end
end
end
- destroyアクション実装
api/app/controllers/api/v1/posts_controller.rb
module Api
module V1
class PostsController < ApplicationController
...省略
def destroy
post = Post.find(params[:id])
if post.destroy
render json: '削除に成功しました', status: 200
else
render json: '削除に失敗しました', status: 500
end
end
end
end
end

これでNuxtとRailsで単一モデルのCRUDを作成することができました。