Written by Manabu Bannai

LaravelとAngularJSでコメントシステムを作ってみた

Laravel PROGRAMMING

LaravelとAngularJSでコメントシステムをつくりました。
参考情報は以下となります。(※英語)
Create a Laravel and Angular Single Page Comment Application Scotch

完成図は以下のとおりです。
comment_app

それではまとめていきます。

Laravelのインストール


$ composer create-project laravel/laravel Comment_Application --prefer-dist

DBの作成


$ php artisan migrate:make create_comments_table --create=comments

生成されたファイルに以下を記述します。


use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreateCommentsTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('comments', function(Blueprint $table)
		{
			$table->increments('id');

			$table->string('text');
			$table->string('author');
			
			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::drop('comments');
	}

}

つぎにマイグレーションします。


$ php artisan migrate

コメントモデルの作成


// app/models/Comment.php

class Comment extends Eloquent {
	// 以下のDB情報に書き込みを許可する
	protected $fillable = array('author', 'text');
}

DBにダミーデータを生成する

CommentTableSeeder.phpを作成します。


// app/database/seeds/CommentTableSeeder.php

class CommentTableSeeder extends Seeder
{
	public function run()
	{
		DB::table('comments')->delete();

		Comment::create(array(
			'author' => '名無しさん',
			'text' => '今日はいい天気ですね。気持ちが良いですね。'
		));

		Comment::create(array(
			'author' => '山田さん',
			'text' => '久しぶり。山田です。'
		));

		Comment::create(array(
			'author' => '太郎さん',
			'text' => 'Laravelって便利なんですね。はじめて知りました。'
		));
	}

}

つぎに、DatabaseSeeder.phpを以下のように編集します。



class DatabaseSeeder extends Seeder {

	/**
	 * Run the database seeds.
	 *
	 * @return void
	 */
	public function run()
	{
		Eloquent::unguard();

		$this->call('CommentTableSeeder');
		$this->command->info('Comment table seeded.');
	}

}

ダミーデータ送信の実行( ◜◡‾)


$ php artisan db:seed

リソースコントローラーを作成する

以下のコマンドを実行します。


$ php artisan controller:make CommentController

コメントコントローラーには以下を記述します。



class CommentController extends BaseController {

	/**
	 * Display a listing of the resource.
	 *
	 * @return Response
	 */
	public function index()
	{
		return Response::json(Comment::get());
	}


	/**
	 * Store a newly created resource in storage.
	 *
	 * @return Response
	 */
	public function store()
	{
		Comment::create(array(
			'author' => Input::get('author'),
			'text' => Input::get('text')
		));

		return Response::json(array('success' => true));
	}

	/**
	 * Remove the specified resource from storage.
	 *
	 * @param  int  $id
	 * @return Response
	 */
	public function destroy($id)
	{
		Comment::destroy($id);

		return Response::json(array('success' => true));
	}


}

ルーティングの設定をする

以下のように作成します。


// app/routes.php

Route::get('/', function()
{
	return View::make('index'); // app/views/index.php を出力する
});


// ルートグループ
// フィルターをルートのグループに対して使用する必要がある場合に使う。
// それぞれのルートにフィルターを個別に指定する代わりに、ルートグループを使用できます。
Route::group(array('prefix' => 'api'), function()
{
	// array('onry')を使うことで、指定されたコントローラー以外へユーザーアクセスを禁止する。
	Route::resource('comments', 'CommentController',
		array('only' => array('index', 'store', 'destroy')));
});

// 404エラーを登録する
App::missing(function($exception)
{
	return View::make('index');
});

ルーティングを確認してみましょう。

$ php artisan routes

routing

以上でバックエンドのプログラムが完了です。
では、AngularJSでフロントを作っていきましょう。

Angularを設置する

Angularを設置するにあたり、ファイル構造は以下の通りになります。

public/
 ∟ js/
  ∟ controllers/
   ∟ mainCtrl.js
  ∟ services/
   ∟ commentService.js
  ∟ app.js

Angularを記述していく


// public/js/services/commentService.js

angular.module('commentService', [])

	.factory('Comment', function($http) {

		return {
			// すべてのコメントを取得する
			get : function() {
				return $http.get('/api/comments');
			},

			// コメントを保存する。
			save : function(commentData) {
				return $http({
					method: 'POST',
					url: '/api/comments',
					headers: { 'Content-Type' : 'application/x-www-form-urlencoded' },
					data: $.param(commentData)
				});
			},

			// コメントを削除する
			destroy : function(id) {
				return $http.delete('/api/comments/' + id);
			}
		}

	});

Angularコントローラーを作成する


// public/js/controllers/mainCtrl.js

angular.module('mainCtrl', [])

	// コメントサービスをコントローラーに挿入する
	.controller('mainController', function($scope, $http, Comment) {

		// コメントフォームのデータを保持するオブジェクト
		$scope.commentData = {};

		// ロードアイコンの表示
		$scope.loading = true;

		// すべてのコメントを取得して、 $scope.comments にわたす
		Comment.get()
			.success(function(data) {
				$scope.comments = data;
				$scope.loading = false;
			});

		// 送信データのコントローラー
		$scope.submitComment = function() {
			$scope.loading = true;

			// コメントを保存する。
			Comment.save($scope.commentData)
				.success(function(data) {

					// 成功した場合、コメントリストをリフレッシュする
					Comment.get()
						.success(function(getData) {
							$scope.comments = getData;
							$scope.loading = false;
						});

				})
				.error(function(data) {
					console.log(data);
				});
		};

		// コメント削除のコントローラー
		$scope.deleteComment = function(id) {
			$scope.loading = true;

			Comment.destroy(id)
				.success(function(data) {

					// 成功した場合、コメントリストをリフレッシュする
					Comment.get()
						.success(function(getData) {
							$scope.comments = getData;
							$scope.loading = false;
						});

				});
		};

	});

アプリケーションを連携する

ng-appおよびng-controllerを使用してアプリケーションに適用できるようにします。


// public/js/app.js
var commentApp = angular.module('commentApp', ['mainCtrl', 'commentService']);

以上でです。最後にメインのビューをつくります( ◜◡‾)

メインのビューを作成する

以下のとおりとなります。

<!-- app/views/index.php -->
<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Laravel と Angular の コメントシステム</title>
	<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css">
	<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">

	<style>
		body 		{ padding-top:30px; }
		form 		{ padding-bottom:20px; }
		.comment 	{ padding-bottom:20px; }
	</style>

	<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
	<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script>

	<!-- /public フォルダからAngularのリソースを読み込みます -->
	<script src="js/controllers/mainCtrl.js"></script>
	<script src="js/services/commentService.js"></script>
	<script src="js/app.js"></script>

</head>

<body class="container" ng-app="commentApp" ng-controller="mainController">
<div class="col-md-8 col-md-offset-2">

	<div class="page-header">
		<h2>Laravel と Angular の コメントシステム</h2>
	</div>

	<form ng-submit="submitComment()">
	<!-- ng-submit will disable the default form action and use our function -->

		<div class="form-group">
			<input type="text" class="form-control input-sm" name="author" ng-model="commentData.author" placeholder="名前">
		</div>

		<div class="form-group">
			<input type="text" class="form-control input-lg" name="comment" ng-model="commentData.text" placeholder="コメントをどうぞ">
		</div>

		<div class="form-group text-right">
			<button type="submit" class="btn btn-primary btn-lg">コメントする</button>
		</div>
	</form>

	<p class="text-center" ng-show="loading"><span class="fa fa-meh-o fa-5x fa-spin"></span></p>

	<div class="comment" ng-hide="loading" ng-repeat="comment in comments">
		<h3>コメント #{{ comment.id }} <small>by {{ comment.author }}</h3>
		<p>{{ comment.text }}</p>
		<p><a href="#" ng-click="deleteComment(comment.id)" class="text-muted">削除</a></p>
	</div>

</div>
</body>
</html>

以上でコメントシステムが完成しました。
参考になれば幸いです。