Step by Step Ruby on Rails

Ruby on Railsで実際にWebサイトを構築する手順をまとめています。

AngularJSとRails4でRestアプリ作成(8)RailsのバリデーションエラーをAngularJSのビューで表示

前回作成した登録・編集機能にサーバー側でのパリでーションチェックを追加し、Rails側で表示する設定を追加しました。
 
1)Railsモデルにバリデーションを登録
 
nameのカラムを20文字以下に制限します。
 
$ vi app/models/user.rb

class User < ActiveRecord::Base
  validates :name,  presence: true, length: { maximum: 20 }
end

 
2)バリデーションエラーメッセージをAngularJSコントローラで設定
 
Rails側でのバリデーションエラーメッセージは、下記のようにJSONフォーマットでリターンしています。
 
render json: @user.errors, status: :unprocessable_entity
 
①underscore.jsをインクルード
 
underscoreの機能を使用するので下記設定を追加します。
 
・underscore-min.jsを入手し、vendor/assets/javascriptsディレクトリに配置。
・application.jsに追加
 
$ vi app/assets/javascripts/application.js
 
//= require underscore-min
 
②Editコントローラにバリデーションエラーメッセージの設定追加
 
$resourceサービスのcreate、updateアクション失敗時のコールバック関数にバリデーションメッセージを設定します。
 
$ vi app/assets/javascripts/mymodule.js.erb

mymodule.controller("UsersEditCtrl", function($scope, $routeParams, userResource,$location) {
  $scope.submit = function() {
    function success(response) {
      $location.path("/users");
    }
    function failure(response) {
      console.log("failure", response)
      _.each(response.data, function(errors, key) {
        _.each(errors, function(e) {
          $scope.form[key].$dirty = true;
          $scope.form[key].$setValidity(e, false);
        });
      });
    }
    if ($routeParams.id) {
      userResource.update($scope.user, success, failure);
    } else {
      userResource.create($scope.user, success, failure);
    }
  };
  $scope.errorMessage = function(name) {
    var s = $scope.form[name].$error;
    result = [];
    _.each(s, function(key, value) {
      result.push(value);
    });
    return result.join(", ");
  };
});

 
3)ng-classを使ってバリデーションエラー時のCSS設定を追加
 
バリデーションエラー発生時に、動的にBootstrap3の"has-error"CSSクラスを設定します。
これで、エラー発生時に入力項目が赤くなります。
 
$ vi app/assets/javascripts/mymodule.js.erb

  $scope.errorClass = function(name) {
    var s = $scope.form[name];
    return s.$invalid && s.$dirty ? "has-error" : "";
  };

 
4)ビューにエラーを表示する記述追加
 
$ vi app/assets/templates/users/edit.html

<form name="form" ng-submit="submit()" class="form-horizontal" novalidate>

  <div class="form-group" ng-class="errorClass('name')>
    <label class="col-sm-2 control-label" for="name">名前</label>
    <div class="col-sm-10">
      <input class="form-control" ng-model="user.name" type="text" name="name" placeholder="名前" required autofocus>
      <span class="help-block" ng-show="form.name.$invalid && form.name.$dirty">
        {_{errorMessage('name')}}
      </span>
    </div>
  </div>

  <div class="form-group"  ng-class="errorClass('email')">
   :
  </div>
</form>