今回はLaravel5.4で掲示板を作成したいと思います。
一通り完成すれば2チャンみたいに使用できると想定しております。
namespaceとuseの使い方下記参考URL
環境
OS/ミドルウェア | バージョン |
---|---|
CentOS | 7.2.1511 |
Apache | 2.4.6 |
PHP | 5.4.16 |
Laravel | 5.4.33 |
まずは、コマンドラインでDBを作成します。
bbc 用のデータベースを作成します。
データベース作成
[MySQLに接続]
1 2 |
$ mysql -u root -p Enter password: パスワード入力 |
[DB作成コマンド]
1 |
mysql> create database bbc; |
[DBが作成出来たか確認]
1 |
mysql> show databases; |
[実行結果]
1 2 3 4 5 6 7 8 9 10 11 |
+--------------------+ | Database | +--------------------+ | information_schema | | bbc | | blog | | mysql | | performance_schema | | sys | +--------------------+ 6 rows in set (0.00 sec) |
これで、bbcのDBが出来ました。
[DB接続を終了]
1 |
mysql> exit |
DB接続の設定
Laravel5では .env ファイルによって環境ごとの設定を管理するようになっているので 、自分の環境に設定します。
プロジェクトディレクトリまで移動する
[.envファイルのバックアップ]
1 |
$ cp .env .env_bk |
[.envファイルの修正]
1 2 3 4 5 6 7 |
# 自分の環境に設定 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret |
[ディレクトリ移動]
1 |
$ cd config/ |
[database.phpファイルのバックアップ]
1 |
$ cp database.php database.php_bk |
[database.phpファイルの修正]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 自分の環境に設定 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true, 'engine' => null, ], |
env 関数で .env の値を取得して、なければデフォルトの値を使用するようになっています。
DEBUGの有効化とタイムゾーンの設定
[app.phpファイルのバックアップ]
1 |
$ cp app.php app.php_bk |
[app.phpファイルの修正]
1 2 3 4 5 6 7 8 9 10 11 |
'debug' => env('APP_DEBUG', false), # 変更↓ 'debug' => env('APP_DEBUG', true), 'timezone' => 'UTC', # 変更↓ 'timezone' => 'Asia/Tokyo', 'locale' => 'en', # 変更↓ 'locale' => 'ja', |
マイグレーションでテーブル作成
※プロジェクトまで移動してからコマンドを打つ。
[ポストテーブル]
1 |
$ php artisan make:migration create_posts_table --create=posts |
[実行結果]
1 |
Created Migration: 2017_08_29_105311_create_posts_table |
[カテゴリーテーブル]
1 |
$ php artisan make:migration create_categories_table --create=categories |
[実行結果]
1 |
Created Migration: 2017_08_29_105744_create_categories_table |
[コメントテーブル]
1 |
$ php artisan make:migration create_comments_table --create=comments |
[実行結果]
1 |
Created Migration: 2017_08_29_105826_create_comments_table |
※Laravelの規約に従うために、データベース名は必ず複数形に。
上記3つのコマンドで、テーブルを作るための「マイグレーションファイル」がそれぞれ作成される。
ファイルの場所は、プロジェクト名/database/migrationsの中に、日付時刻_create_テーブル名_table.phpファイルが生成される
マイグレーションファイルを変更
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd database/migrations |
[ファイルの編集]
1 2 |
// ポストテーブル $ vi 日付時刻_create_posts_table.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePostsTable extends Migration { /** * マイグレーション実行 * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('title'); $table->string('cat_id'); // ポストテーブルとカテゴリーテーブルの紐付けに利用します $table->text('content'); $table->unsignedInteger('comment_count'); // 投稿に何件のコメントがついたのかをカウントします $table->timestamps(); $table->softDeletes(); }); } /** * マイグレーションを元に戻す * * @return void */ public function down() { Schema::drop('posts'); } } |
// useを使うと、Illuminate\Support\Facades\Schemaというnamespace(名前空間)のエイリアスを作成し、Schemaで参照できるようになります!
// useを使うと、Illuminate\Database\Schema\Blueprintというnamespace(名前空間)のエイリアスを作成し、Blueprintで参照できるようになります!
// useを使うと、Illuminate\Database\Migrations\Migrationというnamespace(名前空間)のエイリアスを作成し、Migrationで参照できるようになります!
マイグレーションはupとdownの2メソッドを含んでいます。upメソッドは新しいテーブル、カラム、インデックスをデータベースに追加するために使用し、一方のdownメソッドはupメソッドが行った操作を元に戻します。
新しいデータベーステーブルを作成するには、Schemaファサードのcreateメソッドを使用します。createメソッドは引数を2つ取ります。最初はテーブルの名前で、2つ目は新しいテーブルを定義するために使用するBlueprintオブジェクトを受け取る「クロージャー」です。
[ファイルの編集]
1 2 |
// カテゴリー $ vi 日付時刻_create_categories_table.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCategoriesTable extends Migration { /** * マイグレーション実行 * * @return void */ public function up() { Schema::create('categories', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->timestamps(); $table->softDeletes(); }); } /** * マイグレーションを元に戻す * * @return void */ public function down() { Schema::drop('categories'); } } |
[ファイルの編集]
1 2 |
// コメント $ vi 日付時刻_create_comments_table.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCommentsTable extends Migration { /** * マイグレーション実行 * * @return void */ public function up() { Schema::create('comments', function (Blueprint $table) { $table->increments('id'); $table->unsignedInteger('post_id'); // ポストテーブルとコメントテーブルの紐付けに利用します $table->string('commenter'); $table->text('comment'); $table->timestamps(); $table->softDeletes(); }); } /** * マイグレーションを元に戻す * * @return void */ public function down() { Schema::drop('comments'); } } |
マイグレーションを実行する
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動 $ cd ../../ |
[テーブルを実際に作成するコマンド]
※プロジェクトまで移動してからコマンドを打つ。そうしないと[Could not open input file: artisan]のメッセージが表示される。
1 |
$ php artisan migrate |
[実行結果]
1 2 3 4 5 6 7 8 9 10 11 |
Migration table created successfully. Migrating: 日付時刻_create_users_table Migrated: 日付時刻_create_users_table Migrating: 日付時刻_create_password_resets_table Migrated: 日付時刻_create_password_resets_table Migrating: 日付時刻_create_posts_table Migrated: 日付時刻_create_posts_table Migrating: 日付時刻_create_categories_table Migrated: 日付時刻_create_categories_table Migrating: 日付時刻_create_comments_table Migrated: 日付時刻_create_comments_table |
モデルの作成
※プロジェクトまで移動してからコマンドを打つ。
[ポスト]
1 |
$ php artisan make:model Post |
[実行結果]
1 |
Model created successfully. |
[カテゴリー]
1 |
$ php artisan make:model Category |
[実行結果]
1 |
Model created successfully. |
[コメント]
1 |
$ php artisan make:model Comment |
[実行結果]
1 |
Model created successfully. |
ファイルの場所は、プロジェクト名/appの中に、☓☓☓.phpファイルが生成される。
モデル作成時にデータベースマイグレーションも生成したければ、--migration
か-m
オプションを使ってください。
1 2 3 |
php artisan make:model モデル名 --migration php artisan make:model モデル名 -m |
参考URLはコチラ⇒Laravel 5.4 Eloquent:利用の開始
リレーションの設定
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/ |
[ファイルの編集]
1 2 |
// ポスト $ vi Post.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * ブログポストのコメントを取得 */ public function Comments(){ // 投稿はたくさんのコメントを持つ(hasManyの第2引数が、post_idで、第3引数が、idの場合は省略することができます。) return $this->hasMany('App\Comment', 'post_id'); } /** * ブログポストのカテゴリーを取得 */ public function Category(){ // 投稿は1つのカテゴリーに属する(belongsToの第2引数が、cat_idで、第3引数がidの場合は省略することができます) return $this->belongsTo('App\Category', 'cat_id'); } } |
namespace(名前空間)
PHPでは、定義済みのクラス名、関数名、定数名は、名前の衝突が起こるので使用できません。そのため、識別子は長くなりがちですが、PHP5.3から追加された名前空間という機能を利用することで名前の衝突を避けることができます。名前空間とは、OSのディレクトリに似た概念で、同じ名前でも名前空間(ディレクトリ)が違えば、使用することができます。
リレーション
要は結合です。
素のSQLでは正規化されたテーブルを結合するにはJOIN句を利用しますが、これをEloquentでより簡単にしたいということになります。
1対多
「1対多」リレーションは一つのモデルが他の多くのモデルを所有する関係を定義するために使います。ブログポストが多くのコメントを持つのが一例です。他のEloquentリレーションと同様に1対多リレーションはEloquentモデルの関数として定義します。
hasMany
hasMany(モデル名,外部キー,内部キー)
hasManyは、hasOneと同様に第1引数に関連づけをするモデル名を記述します。第2引数に外部キー、第3引数に内部キーを指定するところも同様です。第2引数の外部キーと第3引数の内部キーを省略できるところも同様です。つまり、引数の記述方法は全く同じです。
それでは、何が違うのでしょうか。hasOneとhasManyでは、関連モデルの紐付けが違います。hasOneでは、一つのモデルに対して一つの関連モデルが紐付けされていましたが、hasManyでは、一つのモデルに対して複数のモデルが紐付けされています。 ですので、hasOneとhasManyの一番の違いは、紐付けされているモデルが一つなのか、複数なのかの違いがあります。
belongsTo(逆の関係の定義)
hasOneの逆のリレーションを定義するには、belongsToメソッドを使います。
belongsTo(モデル名,外部キー,内部キー)
上の例でEloquentはPostモデルのcat_idに一致するidを持つCategoryモデルを見つけようとします。Eloquentはリレーションメソッド名に_idのサフィックスを付けた名前をデフォルトの外部キー名とします。しかしPostモデルの外部キーがcat_idでなければ、belongsToメソッドの第2引数にカスタムキー名を渡してください。
[ファイルの編集]
1 2 |
// カテゴリー $ vi Category.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Category extends Model { // } |
[ファイルの編集]
1 2 |
// コメント $ vi Comment.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { // } |
ダミーデータの作成
Seed機能をつかってダミーデータを生成します。 まず、Seederファイルを作成します。
database/seeds/PostCommentSeeder.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd database/seeds/ |
[ファイル作成]
1 |
$ touch PostCommentSeeder.php |
[ファイルの編集]
1 |
$ vi PostCommentSeeder.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?php use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; use App\Category; use App\Comment; use App\Post; use Faker\Factory as Faker; class PostCommentSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // postsテーブルを一旦削除 truncateはIDもリセットされる Post::truncate(); Category::truncate(); Comment::truncate(); // Fakerを使う ダミーデータを作成してくれる $faker = Faker::create('ja_JP'); $content = 'この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。この文章はダミーです。文字の大きさ、量、字間、行間等を確認するために入れています。'; $commentdammy = 'コメントダミーです。ダミーコメントだよ。'; // insert レコードを10個挿入 for( $i = 1 ; $i <= 10 ; $i++) { $post = new Post; $post->title = "$i 番目の投稿"; $post->content = $content; $post->cat_id = 1; $post->comment_count = 0; $post->save(); // 乱数の範囲を指定し、3~15の間で乱数を生成 $maxComments = mt_rand(3, 15); for ($j=0; $j <= $maxComments; $j++) { $comment = new Comment; $comment->commenter = '名無しさん'; $comment->comment = $commentdammy; // モデル(Post.php)のCommentsメソッドを読み込み、post_idにデータを保存する $post->comments()->save($comment); // カラム値の増加 $post->increment('comment_count'); } } // カテゴリーを追加する $cat1 = new Category; $cat1->name = "電化製品"; $cat1->save(); $cat2 = new Category; $cat2->name = "食品"; $cat2->save(); } } |
データの保存
save()は更新データとの差分を見て更新するか決めてる
※$commentは自ら$comment->save()しようとすると、外部キー制約に引っかかりINSERTできない。必ず、$post->comments()からsaveしてやる必要がある。
外部キー制約
外部キー制約とは、テーブルの指定したカラムに格納できる値を他のテーブルに格納されている値だけに限定するものです。参照される側のテーブルを親テーブル、参照する側のテーブルを子テーブルと呼びます。「親 postsテーブル、カラムid」、「子 commentsテーブル、カラムpost_id」
mt_rand
int mt_rand ( int $min , int $max )
mt_rand (最小値, 最大値(省略可));
カラム値の増加/減少
クエリービルダーは指定したカラムの値を増やしたり、減らしたりするのに便利なメソッドも用意しています。これはシンプルな短縮記法で、update分で書くのに比べるとより記述的であり、簡潔なインターフェイスを提供しています。
両方のメソッドともに変更したいカラムを第1引数に指定します。オプションの第2引数はそのカラムの増減値を指定します。第2引数なしの場合、自動増分
次のコマンドを実行します。
[実行コマンド]
1 |
$ php artisan db:seed --class=PostCommentSeeder |
※実行結果は何も表示されない。エラーが出なければOK
リソースコントローラーを生成する
プロジェクトまでディレクトリを移動します。
[コマンド]
1 |
$ php artisan make:controller PostsController |
ファイルの場所は、プロジェクト名/
app/Http/Controllersに作成される。
app/Http/Controllers/PostsController.php
[ディレクトリの移動]
1 |
$ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi PostsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; use View; class PostsController extends Controller { public function index() { // postsテーブルの全データを取得 $posts = Post::all(); // 結果をビューに送る return View('bbc.index')->with('posts', $posts); } } |
全データ取得
$posts = Post::all();
Eloquentのallメソッドはモデルテーブルの全レコードを結果として返します。
PHP
PHPコードをビューへ埋め込むと便利な場合もあります。Bladeの@php
ディレクティブを使えば、テンプレートの中でプレーンなPHPブロックを実行できます。
ビューへデータを送る
1 |
view(‘view名’)->with(‘viewでの変数名’,’実データ’); |
取得したデータは with() を利用し、ビューへ送る。
ルーティングの設定
routes/web.php
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); // 追加 Route::get('bbc','PostsController@index')->name('bbc.index'); |
ルーティング
ルーティングとは「ページを見ている人が ☓☓☓.☓☓.☓☓☓.☓☓/index
という URL にアクセスをしたら HogehogeController
の hoge()
というメソッドを通りますよ」というような設定をしてあげること。
フレームワークにおいて大事な要素となる。
Laravelにおけるルーティングは、route/web.php
にまとめて記述していく。
「HTTPリクエストが GET で http://☓☓☓.☓☓.☓☓☓.☓☓/bbc にアクセスされたら、PostsController の index() メソッドを通ってね。別名(View名)は bbc.index だよ。」と記述してある。
[ルーティングを確認]
1 2 |
// プロジェクトまで移動して $ php artisan route:list |
[実行結果]
1 2 3 4 5 6 7 |
+--------+----------+----------+-----------+--------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+----------+-----------+--------------------------------------------+--------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api,auth:api | | | GET|HEAD | bbc | bbc.index | App\Http\Controllers\PostsController@index | web | +--------+----------+----------+-----------+--------------------------------------------+--------------+ |
共通テンプレート作成
resources/views/layouts/default.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/layouts/ |
[ファイル作成]
1 |
$ touch default.blade.php |
[ファイルの編集]
1 |
$ vi default.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE HTML> <html lang="ja"> <head> <meta charset="utf-8" /> <!-- bootstrap --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css"> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> <title>Laravelの掲示板</title> </head> <body> @yield('content') </body> </html> |
lang=”ja”
HTMLのlang属性は、要素内で使用されている言語を表記する属性です。よく見かけるのが、<html lang=”ja”>という記述だと思います。これは、html要素内で使われている言語はja、つまり日本語ですよという意味です。
@yield(‘content’)
bodyタグの中に @yield(‘content’) と記入しました。この箇所が実際のページのコンテンツを流し込む箇所になります。
引数で渡している ‘content’ は 複数の@yieldがある場合に、場所を特定する為の名前になります。
一覧用の画面を作成
resources/views/bbc/index.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/ |
[ディレクトリの作成]
1 |
$ mkdir bbc |
[ディレクトリの移動]
1 |
$ cd bbc |
[ファイル作成]
1 |
$ touch index.blade.php |
[ファイルの編集]
1 |
$ vi index.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> @foreach($posts as $post) <h2>タイトル:{{ $post->title }} <small>投稿日:{{ date("Y年 m月 d日",strtotime($post->created_at)) }}</small> </h2> <p>カテゴリー:{{ $post->category->name }}</p> <p>{{ $post->content }}</p> <p>{{ link_to("/bbc/{$post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p> <p>コメント数:{{ $post->comment_count }}</p> <hr /> @endforeach </div> @endsection |
@extends('layouts.default')
で先ほど作成した共通レイアウトを読み込み、@section('content')
… @endsection
で content を定義している。
$post->category->nameに関して
Post.phpモデルのCategory()メソッドからカテゴリー名を取得しています。
Eloquent ORMの便利な機能です。
link_to
指定されたURLへのHTMLリンクを生成します。
link_to を使って、’/bbc/{$post->id}’へのリンクタグを作成します。bootstrap3のclassを設定して、リンクタグをボタンの様に表示します。
1 |
link_to(URL,文字列,bootstrap3のclass) |
PHP
PHPコードをビューへ埋め込むと便利な場合もあります。Bladeの@php
ディレクティブを使えば、テンプレートの中でプレーンなPHPブロックを実行できます。
1 2 3 |
@php // @endphp |
link_toを使用出来るように対応
Laravel5になってlink_toヘルパーが使用できなくなっています。
私の場合は、エラーが出てかなりハマりました…
以下に対応策を書いておきます。
まずは、ディレクトリをプロジェクトまで移動してください。
[ファイルの編集]
1 |
$ vi composer.json |
[ファイルの中身]
1 2 3 4 5 6 7 |
"require": { "php": ">=5.6.4", "laravel/framework": "5.4.*", "laravel/tinker": "~1.0", // 追加 "laravelcollective/html": "5.2.*" }, |
[ファイルの編集]
1 |
$ vi config/app.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
'providers' => [ /* * Laravel Framework Service Providers... */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, // 追加 Collective\Html\HtmlServiceProvider::class, ], 'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, 'Blade' => Illuminate\Support\Facades\Blade::class, 'Broadcast' => Illuminate\Support\Facades\Broadcast::class, 'Bus' => Illuminate\Support\Facades\Bus::class, 'Cache' => Illuminate\Support\Facades\Cache::class, 'Config' => Illuminate\Support\Facades\Config::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class, 'Crypt' => Illuminate\Support\Facades\Crypt::class, 'DB' => Illuminate\Support\Facades\DB::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Event' => Illuminate\Support\Facades\Event::class, 'File' => Illuminate\Support\Facades\File::class, 'Gate' => Illuminate\Support\Facades\Gate::class, 'Hash' => Illuminate\Support\Facades\Hash::class, 'Lang' => Illuminate\Support\Facades\Lang::class, 'Log' => Illuminate\Support\Facades\Log::class, 'Mail' => Illuminate\Support\Facades\Mail::class, 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redis' => Illuminate\Support\Facades\Redis::class, 'Request' => Illuminate\Support\Facades\Request::class, 'Response' => Illuminate\Support\Facades\Response::class, 'Route' => Illuminate\Support\Facades\Route::class, 'Schema' => Illuminate\Support\Facades\Schema::class, 'Session' => Illuminate\Support\Facades\Session::class, 'Storage' => Illuminate\Support\Facades\Storage::class, 'URL' => Illuminate\Support\Facades\URL::class, 'Validator' => Illuminate\Support\Facades\Validator::class, 'View' => Illuminate\Support\Facades\View::class, // 追加 'Form' => Collective\Html\FormFacade::class, // 追加 'Html' => Collective\Html\HtmlFacade::class, ], |
[Laravel集合パッケージをインストール]
1 |
$ composer require "laravelcollective/html":"^5.2.0" |
[実行結果]
1 2 3 4 5 6 7 8 9 10 11 12 |
./composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 1 install, 0 updates, 0 removals - Installing laravelcollective/html (v5.4.9): Downloading (100%) Package illuminate/html is abandoned, you should avoid using it. Use laravelcollective/html instead. Writing lock file Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postUpdate > php artisan optimize Generating optimized class loader The compiled services file has been removed. |
ここで画面の確認をしてみます。
大きく Laravel の文字が出ていたページの URL に「/bbc」を足すとindexページが見られる。
続きを読むボタンを作っていく
現状では、続きを読むボタンは動きません。
続きを読むボタンを動かすためにコントローラーを作ります。
編集ファイル:app/Http/Controllers/PostsController.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Controllers |
[ファイルの編集]
1 |
$ vi PostsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; use View; class PostsController extends Controller { public function index() { // テーブルの全データを取得 $posts = Post::all(); // 結果をビューに送る return View('bbc.index')->with('posts', $posts); } // 追加 public function show($id) { // レコードを検索 $post = Post::find($id); // 検索結果をビューに渡す return view('bbc.single')->with('post', $post); } } |
※find() は指定したIDのレコードを単一のオブジェクトで返します。
つぎにビューをつくります。
新規に作成ファイル:resources/views/bbc/single.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc/ |
[ファイル作成]
1 |
$ touch single.blade.php |
[ファイルの編集]
1 |
$ vi single.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <h2>タイトル:{{ $post->title }} <small>投稿日:{{ date("Y年 m月 d日", strtotime($post->created_at)) }}</small> </h2> <p>カテゴリー:{{ $post->category->name }}</p> <p>{{ $post->content }}</p> <hr /> <h3>コメント一覧</h3> @foreach($post->comments as $single_comment) <h4>{{ $single_comment->commenter }}</h4> <p>{{ $single_comment->comment }}</p><br /> @endforeach </div> @stop |
ルーティングの設定をします。
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Route::get('bbc','PostsController@index')->name('bbc.index'); // 追加 Route::get('bbc/{id}', 'PostsController@show')->name('bbc.show'); |
ページが表示されるか確認します。
投稿機能
ビューを作ります。
resources/views/bbc/create.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc |
[ファイル作成]
1 |
$ touch create.blade.php |
[ファイルの編集]
1 |
$ vi create.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <h1>投稿ページ</h1> {{-- 投稿完了時にフラッシュメッセージを表示 --}} @if(Session::has('message')) <div class="bg-info"> <p>{{ Session::get('message') }}</p> </div> @endif {{-- エラーメッセージの表示 --}} @foreach($errors->all() as $message) <p class="bg-danger">{{ $message }}</p> @endforeach {!! Form::open(['route' => 'bbc.store'], array('class' => 'form')) !!} <div class="form-group"> <label for="title" class="">タイトル</label> <div class=""> {!! Form::text('title', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <label for="cat_id" class="">カテゴリー</label> <div class=""> <select name="cat_id" type="text" class=""> <option></option> <option value="1" name="1">電化製品</option> <option value="2" name="2">食品</option> </select> </div> </div> <div class="form-group"> <label for="content" class="">本文</label> <div class=""> {!! Form::textarea('content', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">投稿する</button> </div> {!! Form::close() !!} </div> @endsection |
以下のページが完成しました。
コントローラーにビューの呼び出しを追加します。
app/Http/Controllers/PostsController.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi PostsController.php |
[ファイルの中身]
1 2 3 4 5 |
public function create() { // 検索結果をビューに渡す return view('bbc.create'); } |
投稿ボタンをクリックした時の動作も追加します
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
use App\Http\Requests\PostStoreRequest; public function store(PostStoreRequest $request) { /** * 投稿した内容を登録 */ $post = new Post; $post->title = $request->get('title'); $post->content = $request->get('content'); $post->cat_id = $request->get('cat_id'); $post->comment_count = 0; $post->save(); return redirect()->back()->with('message', '投稿が完了しました。'); } |
FormRequestという機能を使うためにPostStoreRequestクラスを作成してそれを 読み込んでいます。 そのため、store() はシンプルになっています。 PostStoreRequestの内容は以下のとおりです。
[フォームリクエストを生成]
1 2 |
// プロジェクトまで移動して $ php artisan make:request PostStoreRequest |
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Requests |
[ファイルの編集]
1 |
$ vi PostStoreRequest.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class PostStoreRequest extends FormRequest { /** * リクエストに適用するバリデーションルールを取得 * * @return array */ public function rules() { return [ 'title' => 'required', 'content' => 'required', 'cat_id' => 'required' ]; } /** * 定義済みバリデーションルールのエラーメッセージ取得 * * @return array */ public function messages() { return [ 'title.required' => 'タイトルを正しく入力してください。', 'content.required' => '本文を正しく入力してください。', 'cat_id.required' => 'カテゴリーを選択してください。', ]; } /** * ユーザーがこのリクエストの権限を持っているかを判断する * * @return bool */ public function authorize() { return true; } } |
FormRequestクラスを継承して、バリデートの内容をrules()で、 カスタムメッセージの内容をmessages()でそれぞれ返しています。
createメソッドでデータを挿入するので Postモデルに $fillable プロパティを定義する必要があります。
app/Post.php
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi app/Post.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { // 追加 protected $fillable = ['title', 'content', 'cat_id']; /** * ブログポストのコメントを取得 */ public function Comments(){ // 投稿はたくさんのコメントを持つ return $this->hasMany('App\Comment', 'post_id'); } /** * ブログポストのカテゴリーを取得 */ public function Category(){ // 投稿は1つのカテゴリーに属する return $this->belongsTo('App\Category', 'cat_id'); } } |
これで完成です。
バリデーションエラーがおきると以下のようになります。
投稿するページにリンクがないので作成します。
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc/ |
[ファイルの編集]
1 |
$ vi index.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <!-- ここから --> <br/> <h3> <p>投稿ページ:{{ link_to("/bbc/create/", '投稿する', array('class' => '')) }}</p> </h3> <!-- ここまで追加 --> @foreach($posts as $post) ︙ ︙ ︙ @endforeach </div> @endsection |
ルーティングの設定をします。
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ /* デフォルト */ /*Route::get('/', function () { return view('welcome'); });*/ // 追加 /* リソースに対する様々なアクションを処理する、複数のルートがこの1定義により生成されます */ Route::resource('bbc', 'PostsController'); /* 掲示板一覧 */ //Route::get('bbc','PostsController@index')->name('bbc.index'); /* コメント一覧 */ //Route::get('bbc/{id}', 'PostsController@show')->name('bbc.show'); /* 投稿ページ */ //Route::get('bbc/create','PostsController@create')->name('bbc.create'); |
これで投稿するページにリンクができるようになりました。
特定のカテゴリーに属する記事一覧の表示
まず、index ビューをすこし修正して、カテゴリーをクリックできるようにします。
resources/views/bbc/index.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc |
[ファイルの編集]
1 |
$ vi index.blade.php |
[ファイルの中身]
1 2 3 |
<p>カテゴリー:{{ $post->category->name }}</p> ↓変更 <p>カテゴリー:{{ link_to("/bbc/category/{$post->category->id}", $post->category->name, array('class' => '')) }}</p> |
つぎにコントローラーにshowCategory()メソッドを作成します。
app/Http/Controllers/PostsController.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi PostsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 |
public function showCategory($id) { // 引数で渡された$idでカテゴリーごとにデータを取得 $category_posts = Post::where('cat_id', $id)->get(); // 結果をビューに送る return view('bbc.category')->with('category_posts', $category_posts); } |
つづいて、ビューファイルを作成します。
resources/views/bbc/category.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc/ |
[ファイル作成]
1 |
$ touch category.blade.php |
[ファイルの編集]
1 |
$ vi category.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> @foreach($category_posts as $category_post) <h2>タイトル:{{ $category_post->title }} <small>投稿日:{{ date("Y年 m月 d日",strtotime($category_post->created_at)) }}</small> </h2> <p>{{ $category_post->content }}</p> <p>{{ link_to("/bbc/{$category_post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p> <p>コメント数:{{ $category_post->comment_count }}</p> <hr /> @endforeach </div> @endsection |
最後にルーティングの設定をします。
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ /* デフォルト */ /*Route::get('/', function () { return view('welcome'); });*/ /* リソースに対する様々なアクションを処理する、複数のルートがこの1定義により生成されます */ Route::resource('bbc', 'PostsController'); /* 掲示板一覧 */ //Route::get('bbc','PostsController@index')->name('bbc.index'); /* コメント一覧 */ //Route::get('bbc/{id}', 'PostsController@show')->name('bbc.show'); /* 投稿ページ */ //Route::get('bbc/create','PostsController@create')->name('bbc.create'); // 追加 /* カテゴリー */ Route::get('bbc/category/{id}', 'PostsController@showCategory')->name('bbc.showCategory'); |
これでカテゴリごとの表示ができるようになりました。
コメントの投稿機能
はじめに、ビューを編集します。
resources/views/bbc/single.blade.php コメント一覧の下に追加
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc/ |
[ファイルの編集]
1 |
$ vi single.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<h3>コメントを投稿する</h3> {{-- 投稿完了時にフラッシュメッセージを表示 --}} @if(Session::has('message')) <div class="bg-info"> <p>{{ Session::get('message') }}</p> </div> @endif {{-- エラーメッセージの表示 --}} @foreach($errors->all() as $message) <p class="bg-danger">{{ $message }}</p> @endforeach {!! Form::open(['route' => 'comment.store'], array('class' => 'form')) !!} <div class="form-group"> <label for="commenter" class="">名前</label> <div class=""> {!! Form::text('commenter', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <label for="comment" class="">コメント</label> <div class=""> {!! Form::textarea('comment', null, array('class' => '')) !!} </div> </div> {!! Form::hidden('post_id', $post->id) !!} <div class="form-group"> <button type="submit" class="btn btn-primary">投稿する</button> </div> {!! Form::close() !!} |
次にコントローラーを作成します。
プロジェクトまでディレクトリを移動します。
[コマンド]
1 |
$ php artisan make:controller CommentsController |
[ディレクトリの移動]
1 |
$ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi CommentsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php namespace App\Http\Controllers; use App\Comment; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Http\Requests\CommentStoreRequest; class CommentsController extends Controller { /** * コメントした内容を登録 */ public function store(CommentStoreRequest $request) { $comment = new Comment; $comment->post_id = $request->get('post_id'); $comment->commenter = $request->get('commenter'); $comment->comment = $request->get('comment'); $comment->save(); return redirect()->back()->with('message', 'コメントを投稿しました。'); } } |
PostsController と同じように FormRequestを継承したCommentStoreRequestを使用しています。
CommentStoreRequestの内容は以下のとおりです。
[フォームリクエストを生成]
1 2 |
// プロジェクトまで移動して $ php artisan make:request CommentStoreRequest |
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Requests |
[ファイルの編集]
1 |
$ vi CommentStoreRequest |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class CommentStoreRequest extends FormRequest { /** * リクエストに適用するバリデーションルールを取得 * * @return array */ public function rules() { return [ 'commenter' => 'required', 'comment' => 'required' ]; } /** * 定義済みバリデーションルールのエラーメッセージ取得 * * @return array */ public function messages() { return [ 'commenter.required' => '名前を正しく入力してください。。', 'comment.required' => 'コメントを正しく入力してください。', ]; } /** * ユーザーがこのリクエストの権限を持っているかを判断する * * @return bool */ public function authorize() { return true; } } |
FormRequestクラスを継承して、バリデートの内容をrules()で、 カスタムメッセージの内容をmessages()でそれぞれ返しています。
次にルーティングの設定をします。
routes/web.php
[ファイルの編集]
1 2 |
// プロジェクトまで移動して $ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ /* デフォルト */ /*Route::get('/', function () { return view('welcome'); });*/ /* リソースに対する様々なアクションを処理する、複数のルートがこの1定義により生成されます */ Route::resource('bbc', 'PostsController'); // 追加 Route::resource('comment', 'CommentsController'); /* カテゴリー */ Route::get('bbc/category/{id}', 'PostsController@showCategory')->name('bbc.showCategory'); |
これでコメントの投稿ができるようになりました。
ページネーション
Laravel5 ではすでにページネーション機能が組み込まれています。
ですのでページネーションの実装は簡単です。
Controller
app/Http/Controllers/PostsController.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi PostsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** * 掲示板の一覧表示 */ public function index() { // 変更前 $posts = Post::all(); ↓ // 変更後 $posts = Post::paginate(10); return View('bbc.index')->with('posts', $posts); } |
pagenate()の引数の “10” が1ページに表示するデータ数です。
View
resources/views/bbc/index.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc |
[ファイルの編集]
1 |
$ vi index.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <br/> <h3> <p>投稿ページ:{{ link_to("/bbc/create/", '投稿する', array('class' => '')) }}</p> </h3> @foreach($posts as $post) <h2>タイトル:{{ $post->title }} <small>投稿日:{{ date("Y年 m月 d日",strtotime($post->created_at)) }}</small> </h2> <p>カテゴリー:{{ link_to("/bbc/category/{$post->category->id}", $post->category->name, array('class' => '')) }}</p> <p>{{ $post->content }}</p> <p>{{ link_to("/bbc/{$post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p> <p>コメント数:{{ $post->comment_count }}</p> <hr /> @endforeach <!-- 追加 --> {{ $posts->links() }} </div> @endsection |
これだけでクエリストリングスからpageという値を自動で読み取ってくれます。
動作確認をすると生成するリンクにも?page=xxxが付与されているのがわかります。
掲示板の一番下にページの切り替えボタンが作成されていることを確認して下さい。
戻るボタン
resources/views/bbc/create.blade.php
[ディレクトリの移動]
1 2 |
// プロジェクトまで移動して $ cd resources/views/bbc/ |
[ファイルの編集]
1 |
$ vi create.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <h1>投稿ページ</h1> {{-- 投稿完了時にフラッシュメッセージを表示 --}} @if(Session::has('message')) <div class="bg-info"> <p>{{ Session::get('message') }}</p> </div> @endif {{-- エラーメッセージの表示 --}} @foreach($errors->all() as $message) <p class="bg-danger">{{ $message }}</p> @endforeach {!! Form::open(['route' => 'bbc.store'], array('class' => 'form')) !!} <div class="form-group"> <label for="title" class="">タイトル</label> <div class=""> {!! Form::text('title', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <label for="cat_id" class="">カテゴリー</label> <div class=""> <select name="cat_id" type="text" class=""> <option></option> <option value="1" name="1">電化製品</option> <option value="2" name="2">食品</option> </select> </div> </div> <div class="form-group"> <label for="content" class="">本文</label> <div class=""> {!! Form::textarea('content', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">投稿する</button> <!-- 追加 --> <a class="btn btn-default" href="#" onClick="history.back(); return false;">戻る</a> </div> {!! Form::close() !!} </div> @endsection |
href="#"
というのは「そのページの最上部へのリンク」という意味で、スクロールした場所から一番上に戻したい場合に使います。
return false
を書くと、そのリンクがクリックされた時に history.back() という関数を実行し、他の処理はするな、という意味です。
history.back()
… 1つ前に戻る
以下のように戻るボタンが作成されます。
resources/views/bbc/single.blade.php
[ファイルの編集]
1 |
$ vi single.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <h2>タイトル:{{ $post->title }} <small>投稿日:{{ date("Y年 m月 d日", strtotime($post->created_at)) }}</small> </h2> <p>カテゴリー:{{ $post->category->name }}</p> <p>{{ $post->content }}</p> <hr /> <h3>コメント一覧</h3> @foreach($post->comments as $single_comment) <h4>{{ $single_comment->commenter }}</h4> <p>{{ $single_comment->comment }}</p><br /> @endforeach <h3>コメントを投稿する</h3> {{-- 投稿完了時にフラッシュメッセージを表示 --}} @if(Session::has('message')) <div class="bg-info"> <p>{{ Session::get('message') }}</p> </div> @endif {{-- エラーメッセージの表示 --}} @foreach($errors->all() as $message) <p class="bg-danger">{{ $message }}</p> @endforeach {!! Form::open(['route' => 'comment.store'], array('class' => 'form')) !!} <div class="form-group"> <label for="commenter" class="">名前</label> <div class=""> {!! Form::text('commenter', null, array('class' => '')) !!} </div> </div> <div class="form-group"> <label for="comment" class="">コメント</label> <div class=""> {!! Form::textarea('comment', null, array('class' => '')) !!} </div> </div> {!! Form::hidden('post_id', $post->id) !!} <div class="form-group"> <button type="submit" class="btn btn-primary">投稿する</button> <!-- 追加 --> <a class="btn btn-default" href="#" onClick="history.back(); return false;">戻る</a> </div> {!! Form::close() !!} </div> @stop |
以下のように戻るボタンが作成されます。
resources/views/bbc/category.blade.php
[ファイルの編集]
1 |
$ vi category.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
@extends('layouts.default') @section('content') <div class="col-xs-8 col-xs-offset-2"> <br/> <!-- ここから --> <h3> 戻るボタン:<a class="btn btn-default" href="#" onClick="history.back(); return false;">戻る</a> </h3> <hr /> <!-- ここまで追加 --> @foreach($category_posts as $category_post) <h2>タイトル:{{ $category_post->title }} <small>投稿日:{{ date("Y年 m月 d日",strtotime($category_post->created_at)) }}</small> </h2> <p>{{ $category_post->content }}</p> <p>{{ link_to("/bbc/{$category_post->id}", '続きを読む', array('class' => 'btn btn-primary')) }}</p> <p>コメント数:{{ $category_post->comment_count }}</p> <hr /> @endforeach </div> @endsection |
以下のように戻るボタンが作成されます。
削除ボタン
app/Comment.php
[ファイルの編集]
1 |
$ vi app/Comment.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Comment extends Model { use SoftDeletes; /** * 日付へキャストする属性 * * @var array */ protected $dates = ['deleted_at']; } |
ソフトデリートの処理を追加。詳しくはコチラ⇒Laravel 5.4 Eloquent:利用の開始
app/Http/Controllers/CommentsController.php
[ディレクトリの移動]
1 |
$ cd app/Http/Controllers/ |
[ファイルの編集]
1 |
$ vi CommentsController.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<?php namespace App\Http\Controllers; use App\Comment; use DB; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use App\Http\Requests\CommentStoreRequest; class CommentsController extends Controller { /** * コメントした内容をcommentsテーブルに登録 * comment_countを+1してpostsテーブルにアップデート */ public function store(CommentStoreRequest $request) { // $requestのデータがあったら処理 if($request != NULL or $request != "") { // コメントしているpost_idを基にpostsテーブルからデータを取得 $posts = DB::table('posts')->where('id', $request->get('post_id'))->first(); // $postsにデータがある場合は処理 if($posts != NULL or $posts != "") { // postsテーブルのコメントカウント数を+1 $comment_count = $posts->comment_count + 1; // postsテーブルのcomment_countをアップデート DB::table('posts')->where('id', $request->get('post_id'))->update(['comment_count' => $comment_count]); } // DBにデータを入れる処理 $comment = new Comment; $comment->post_id = $request->get('post_id'); $comment->commenter = $request->get('commenter'); $comment->comment = $request->get('comment'); $comment->save(); return redirect()->back()->with('message', 'コメントを投稿しました。'); } } /** * 削除ボタン */ public function deletButton(Request $request) { // $requestのデータがあったら処理 if($request != NULL or $request != "") { // FormからPOST値のvalueの値を取得して、文字列を文字列により分割する。formのnameに設定したものを引数にする。 $array = explode(',', $request->input('id')); $id = $array[0]; $post_id = $array[1]; // postテーブルのデータを取得 $posts = DB::table('posts')->where('id', $post_id)->first(); // $postsにデータがある場合は処理 if($posts != NULL or $posts != "") { // postsテーブルのコメントカウント数を-1 $comment_count = $posts->comment_count - 1; // postsテーブルのcomment_countをアップデート DB::table('posts')->where('id', $post_id)->update(['comment_count' => $comment_count]); } // ソフトデリートで削除処理(commentsテーブルのdeleted_atに削除処理をした時の時間がアップデートされる) Comment::where('id', (int)$id)->delete(); // 確認メッセージ表示 return redirect()->back()->with('message', 'コメントを削除しました。'); } } } |
既存の書いてある中身をけっこう変更しているでファイルごとコピーで上書きしていいレベルです。(笑)
resources/views/bbc/single.blade.php
[ディレクトリの移動]
1 |
$ cd resources/views/bbc/ |
[ファイルの編集]
1 |
$ vi single.blade.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
@extends('layouts.default') @section('content') <!-- ここから --> <script type="text/javascript"> $(document).on('click','#delet-button', function() { // 確認ダイアログ if(confirm("削除しますか?") === false) { return false; } }); </script> <!-- ここまで追加 --> <div class="col-xs-8 col-xs-offset-2"> ︙ <h3>コメント一覧</h3> @foreach($post->comments as $single_comment) <h4>{{ $single_comment->commenter }}</h4> <p>{{ $single_comment->comment }}</p><br /> ↓ 変更(<br />を削除) <p>{{ $single_comment->comment }}</p> <!-- ここから --> {!! Form::open(['route' => 'comment.deletButton'], array('class' => 'form')) !!} <div class="form-group"> <button id="delet-button" name="id" value="{{ $single_comment->id }},{{ $single_comment->post_id }}" class="btn btn-defalt">削除</button><br /> </div> {!! Form::close() !!} <!-- ここまで追加 --> @endforeach ︙ </div> @stop |
routes/web.php
[ファイルの編集]
1 |
$ vi routes/web.php |
[ファイルの中身]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ /* デフォルト */ /*Route::get('/', function () { return view('welcome'); });*/ /* リソースに対する様々なアクションを処理する、複数のルートがこの1定義により生成されま す */ Route::resource('bbc', 'PostsController'); Route::resource('comment', 'CommentsController'); /* カテゴリー */ Route::get('bbc/category/{id}', 'PostsController@showCategory')->name('bbc.showCategory'); // 追加 /* 削除ボタン */ Route::post('comment/delet', 'CommentsController@deletButton')->name('comment.deletButton'); |
以下のように削除ボタンが作成されます。
まとめ
Laravel4とはディレクトリの構成が変わったり、メソッド名、コマンド名が変わったりと すこし戸惑う部分もありましたが、Laraveを初めて使用してみましたが、やり方が分かっていれば結構簡単に色々作成できると感じました。
ConoHaとCentOS7でLaravel5インストール方法
ConoHaとCentOS7でLaravel5.4掲示板の作成