20
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails+Vue.jsでバリデーションエラーを各項目の下に表示する

Posted at

#はじめに
Rails側のモデルに定義したバリデーションを使いつつ、
バリデーションエラーを各項目の下に表示するのに苦労したのでまとめておこうと思います。
今回、バリデーション関連以外の説明は省略させていただきます。
ご了承ください。。

#やりたいこと
このように項目の下にバリデーションエラーを表示するようにします。(見た目は気にしないでください。。)
image.png

#実装してみる
###バリデーションを設定
ここでは必須のバリデーションだけ設定しておきます。

class Company < ApplicationRecord
  validates :name,
    presence: true
end

###API側の実装
vue.js側で各項目ごとのエラーメッセージを取り出せるようにします。
具体的には下記のようなハッシュになるように加工します。
{項目名: 日本語化されたエラーメッセージ}

今回は下記のように実装しました。

@company = Company.new(create_company_params)
if @company.save
  render json: @company, status: :ok
else
  render json: { errors: @company.errors.keys.map { |key| [key, @company.errors.full_messages_for(key)]}.to_h, render: 'show.json.jbuilder' }, status: :unprocessable_entity
end

ここでerrorsにエラーメッセージを設定しています。

errors: @company.errors.keys.map { |key| [key, @company.errors.full_messages_for(key)]}.to_h

API側はこれで終わりです。

##vue.js側で項目の下にエラーが表示されるようにする
まずはtemplateから実装していきます。

<template>
  <form @submit.prevent="createCompany">
    <h2>企業情報</h2>
    <div>
      <label>企業名</label>
      <input v-model="company.name" type="text">
      <!-- これでバリデーションエラーがあるときだけ表示される -->
      <p v-if="!!errors['name']" class="error" style="color: red;">{{ errors['name'][0]}}</p>
    </div>
  </form>
</template>

errorsのkeyの中に表示する項目名が含まれているかどうかで、
表示/非表示を切り替えています。

次にscriptです。

<script>
  import axios from 'axios'
  import { csrfToken } from 'rails-ujs'
  axios.defaults.headers.common['X-CSRF-Token'] = csrfToken()

  export default {
    data: function () {
      return {
        company:{
          name: ''
        },
        // バリデーションエラーがあった場合は、このerrorsにセットされます。
        errors: ''
      }
    },
    methods: {
      createCompany: function(){
        axios
          .post('api/v1/company.json', this.company)
            .then(response => {
              this.$router.push('/');
            })
            .catch(error => {
              if (error.response.data && error.response.data.errors) {
                this.errors = error.response.data.errors;
              }
            });
      }
  }
</script>

これでバリデーションエラーがあるときは各項目の下に表示されるようになるかと思います。

#まとめ
今回は各項目の下にエラーメッセージを表示する方法をまとめました。
もっといい感じの方法があれば、是非コメントで教えてください。。

20
13
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
20
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?