Step by Step Ruby on Rails

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

Ruby on Rails Tutorial フォロー、アンフォローを実行

「Ruby on Rails Tutorial」のサンプルアプリをAngularJSとBootstrap3を使う形にして作成します。前回、ユーザーの詳細画面にfollow/unfollowのボタンを表示しました。今回は、ボタン押下時の動作を定義し、フォロー、アンフォローを実行できるようにします。

1)Railsルート設定

フォロー、アンフォローのフォーム用のルートを定義します。

$ vi config/routes.rb

  match '/app/relationships', to: 'relationships#create',  via: 'post'
  match '/app/relationships', to: 'relationships#destroy', via: 'delete'

2)Railsのrelationshipsコントローラにcreate、destroyアクション定義

$ vi app/controllers/relationships_controller.rb

class RelationshipsController < ApplicationController
  before_action :signed_in_user

  def create
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    @user = User.find(user_params[:id])
    current_user.follow!(@user)
    head :no_content
  end

  def destroy
    remember_token = User.encrypt(cookies[:remember_token])
    current_user ||= User.find_by(remember_token: remember_token)
    @user = User.find(user_params[:id])
    current_user.unfollow!(@user)
    head :no_content
  end

  private
    def user_params
      params.permit(:id)
    end
    def signed_in_user
      remember_token = User.encrypt(cookies[:remember_token])
      current_user ||= User.find_by(remember_token: remember_token)
      if current_user.nil?
        render status: :unauthorized
      end
    end
end

3)AngularJSスクリプトにリソース定義追加

$ vi app/assets/javascripts/mymodule.js.erb

myModule.factory("relationshipsResource", function($resource) {
  return $resource("/app/relationships",{},
    {
      'create':  { method: 'POST' },
      'destroy': { method: 'DELETE' }
    }
  );
});

4)AngularJSコントローラにフォロー、アンフォローの関数を追加

①上記3)で定義した"relationshipsResource"サービスを使ってフォロー、アンフォローの操作を実行。

②実行後、$scope.flg_unfollowを設定し、follow/unfollowのボタンを切り替え。

③ログインユーザーのフォロアー情報が変更されたのでログイン済み情報をflashServiceにセット

④同一ビュー内のフォロアー数などを更新するため$emit("$routeChangeSuccess")を実行。

$ vi app/assets/javascripts/mymodule.js.erb

myModule.controller("UsersShowCtrl", function($scope, $routeParams, userResource, flashService, $filter, micropostsResource, $q, sessionResource, relationshipsResource) {
  :
  $scope.follow = function(id) {
    function success(response) {
      $scope.flg_unfollow = true;
      sessionResource.current_user({}, function(response) {
        flashService.setUser(response);
      });
      $scope.$emit("$routeChangeSuccess");
    }
    function failure(response) {
      console.log("follow error");
    }
    var user_data = {
      id: id
    };
    relationshipsResource.create(user_data, success, failure);
  };

  $scope.unfollow = function(id) {
    relationshipsResource.destroy({ id: id }, function(response) {
      $scope.flg_unfollow = false;
      sessionResource.current_user({}, function(response) {
        flashService.setUser(response);
      });
      $scope.$emit("$routeChangeSuccess");
    });
  };