「Ruby on Rails Tutorial」のサンプルアプリをAngularJSとBootstrap3を使う形にして作成します。ユーザーログイン機能を作成します。今回はまずRailsのコントローラを作成、Railsのルート設定、AngularJSのルート設定、ログインページの作成、ログイン失敗時の処理を作成します。
(1)Railsコントローラを作成、ルート設定
ユーザーログイン時にセッションも管理します。ここでは、sessionsという名前でコントローラを作成し、下記アクションを使用します。
・createアクション
ログインフォームからログイン。HTTPのPOSTリクエスト。セッションを作成。
・destroyアクション
ログアウト。HTTPのDELETEリクエスト。セッションを削除
1)Sessionsコントローラを作成
$ rails generate controller Sessions
2)セッションコントローラのcreateアクション作成
●ユーザーログイン失敗時の処理内容
①ユーザーログインフォームで入力された情報をparamsハッシュから受け取る。
②paramsで受け取ったメールアドレスをキーにユーザーをDBから検索。
③ユーザーが存在した場合、paramsで受け取ったパスワードを基に認証チェック。
④認証が失敗した場合、ログインページにエラーメッセージを表示。
●createアクション作成
入力されたメールアドレスとパスワードを基に認証し、エラーの場合はエラーメッセージを設定し、JSONフォーマットでリターンします。
$ vi app/controllers/sessions_controller.rb
def create user = User.find_by(email: session_params[:email].downcase) if user && user.authenticate(session_params[:password]) else msg = {"password" => ["Invalid email/password combination"]} render json: msg, status: :unprocessable_entity end end private def session_params params.permit(:email,:password) end
3)Railsのルート設定
$ vi config/routes.rb
match ‘/app/sessions’, to: ‘sessions#create’, via: ‘post’
match ‘/app/sessions’, to: ‘sessions#destroy’, via: ‘delete’
(2)AngularJSの$resourceのRESTアクションをサービスとして定義
Railsのサーバー側にAngularJSの$resourceサービスを使ってアクセスするアクションをサービスとして定義します。
$ vi app/assets/javascripts/mymodule.js.erb myModule.factory("sessionResource", function($resource) { return $resource("/app/sessions",{}, { 'create': { method: 'POST' }, 'destroy': { method: 'DELETE' } } ); });
(3)AngularJSのルート設定追加
ログインページ用のルート設定を追加します。
$ vi app/assets/javascripts/mymodule.js.erb
.when(“/signin”, {
templateUrl: “”
})
(4)AngularJSのコントローラを作成
$ vi app/assets/javascripts/mymodule.js.erb
myModule.controller("SessionsNewCtrl", function($scope, sessionResource) { $scope.session = new sessionResource(); $scope.submit = function() { function success(response) { console.log("test"); } function failure(response) { _.each(response.data, function(errors, key) { _.each(errors, function(e) { $scope.sessionNewForm[key].$dirty = true; $scope.sessionNewForm[key].$setValidity(e, false); }); }); } sessionResource.create($scope.session, success, failure); }; $scope.errorMessage = function(name) { var s = $scope.sessionNewForm[name].$error; result = []; _.each(s, function(key, value) { result.push(value); }); return result.join(", "); }; $scope.errorClass = function(name) { var s = $scope.sessionNewForm[name]; return s.$invalid && s.$dirty ? "has-error" : ""; }; });
・ng-classを使ってバリデーションエラー時のCSS設定を追加
バリデーションエラー発生時に、動的にBootstrap3の”has-error”CSSクラスを設定します。これで、エラー発生時に入力項目が赤くなります。
・Railsのコントローラで設定したエラーメッセージをAngularJSのフォーム表示する部分は、以前作成したユーザー登録の場合と同じです。
(5)ユーザーログインフォーム作成
$ vi app/assets/templates/sessions/new.html.erb
<div ng-controller="SessionsNewCtrl" class="row"> <div class="col-md-6 col-md-offset-3"> <h1 class="text-center">Sign in</h1> <div class="well"> <form name="sessionNewForm" ng-submit="submit()" novalidate> <div class="form-group"> <label>Email</label> <input type="email" name="email" class="form-control" ng-model="session.email" required /> </div> <div class="form-group" ng-class="errorClass('password')"> <label>Password</label> <input type="password" name="password" class="form-control" ng-model="session.password" required /> <span class="help-block" ng-show="sessionNewForm.password.$invalid && sessionNewForm.password.$dirty"> {\{errorMessage('password')}} </span> </div> <button type="submit" class="btn btn-large btn-primary">Sign in</button> </form> <p>New user?<a href="/users/new">Sign up now!</a></p> </div> </div> </div>
6)メニューにログインのリンクを追加
$ vi app/views/layouts/_header.html.erb
<li><%= link_to “Sing in”, “/signin” %></li>