Laravelサンプル1

#参照
http://dotinstall.com/lessons/basic_laravel

#ソース
https://github.com/takezawahiroshi/laravel6/tree/master/myblog

Laravel5.2

#作成ファイル

####routes　(※すでにある)
  /var/www/html/myblog/app/Http
  routes.php

####model　(※artisanコマンドで作る)
  /var/www/html/myblog/app
  Post.php
  Comment.php

####controller　(※artisanコマンドで作る)
  /var/www/html/myblog/app/Http/Controllers
  PostsController.php
  CommentsController.php

####view　(※ファイル作る)
  /var/www/html/myblog/resources/views/posts
  create.blade.php
  edit.blade.php
  index.blade.php
  show.blade.php

  /var/www/html/myblog/resources/views/layouts
  default.blade.php

####css　(※ファイル作る)
  /var/www/html/myblog/public/css
  styles.css

####validation　(※artisanコマンドで作る)
  /var/www/html/myblog/app/Http/Requests
  PostRequest.php

####config　(※すでにある)
  /var/www/html/myblog/config
  app.php
  database.php

####migration　(※artisanコマンドで作る)
  /var/www/html/myblog/database/migrations

  2017_02_10_114629_create_posts_table.php
  2017_02_13_110711_create_comments_table.php

####マイグレーションファイルの作成手順

1) artisanコマンドを実行「php artisan make:migration XXXXX」
  database/migrations/に、yyyy_mm_dd_hhmmss_XXXXX が作成される
2) マイグレーションファイルに、up downを記述 (カラムを追加する)
3) マイグレーション実行「$php artisan migration」

  $ php artisan make:migration create_posts_table --create=posts　
  --createオプションでテーブル名を指定すると新規でテーブル作成。

  $ php artisan migration

####モデルを作る(#13)
  $ php artisan make:model post

1) Mass Assignmentを記述する(このカラムにはデータを挿入してもいいという設定をする)

---

####コントローラーを作る(#13)
  $ php artisan make:Controller PostsController

####モデルとマイグレーションファイルを同時に作る(#24)
  $ php artisan make:model Comment --migration

####バリデーションを作る(#21)
  $ php artisan make:request PostRequest

---

#ソース(詳細)

##routes
 routes.php

```/var/www/html/myblog/app/Http/routes.php

<?php

    Route::get('/', 'PostsController@index');
    Route::get('/posts/create', 'PostsController@create');
    Route::get('/posts/{id}', 'PostsController@show');
    Route::get('/posts/{id}/edit', 'PostsController@edit');
    Route::post('/posts', 'PostsController@store');
    Route::patch('/posts/{id}', 'PostsController@update');
    Route::delete('/posts/{id}', 'PostsController@destroy');
    Route::post('/posts/{post}/comments', 'CommentsController@store');
    Route::delete('/posts/{post}/comments/{comment}', 'CommentsController@destroy');
```

##migration
 2017_02_10_114629_create_posts_table.php
 2017_02_13_110711_create_comments_table.php

```/var/www/html/myblog/database/migrations/2017_02_10_114629_create_posts_table.php

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

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

```/var/www/html/myblog/database/migrations/2017_02_13_110711_create_comments_table.php

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCommentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('comments', function (Blueprint $table) {
            $table->increments('id');
            //コメントを post に対して紐付け 
            //負の値になることは無いので、unsigned()
            $table->integer('post_id')->unsigned();
　　　　　　　　　　　　　　　　　　　　　　　　//一行コメントなので string('body')
            $table->string('body');
            $table->timestamps();

　　　　　　　　　　　　　　　　　　　　　　　　//紐付け
            $table->foreign('post_id')
                  ->references('id')
                  ->on('posts')
                  ->onDelete('cascade');
        });
    }

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

##model
 Post.php
 Comment.php

![post.png](https://qiita-image-store.s3.amazonaws.com/0/62264/272829c9-337c-939a-ce2d-51f08b38df8c.png)

![1.png](https://qiita-image-store.s3.amazonaws.com/0/62264/773f90ee-bfef-2499-c952-3b73a05a54ef.png)

```/var/www/html/myblog/app/Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
    protected $fillable = ['title', 'body'];

    public function comments() {
      return $this->hasMany('App\Comment');
    }
}
```
![comment.png](https://qiita-image-store.s3.amazonaws.com/0/62264/21709aa2-ab75-c08a-d771-f2b3bd41772e.png)

![スクリーンショット 2017-02-13 17.32.25.png](https://qiita-image-store.s3.amazonaws.com/0/62264/d8c6e567-9ac6-a8ce-b0fb-06d32d4cddb4.png)


```/var/www/html/myblog/app/Comment.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    //
    protected $fillable = ['body'];

    // comment->post
    public function post() {
      return $this->belongsTo('App\Post');
    }
}
```

##Controller
 PostsController.php
 CommentsController.php

```/var/www/html/myblog/app/Http/Controllers/PostsController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

//追加
use App\Post;
use App\Http\Requests\PostRequest;

class PostsController extends Controller
{
    public function index() {
      $posts = Post::latest('created_at')->get();
      return view('posts.index')->with('posts', $posts);
    }

    public function show($id) {
      $post = Post::findOrFail($id);
      return view('posts.show')->with('post', $post);
    }

    public function edit($id) {
      $post = Post::findOrFail($id);
      return view('posts.edit')->with('post', $post);
    }

    public function destroy($id) {
      $post = Post::findOrFail($id);
      $post->delete();
      return redirect('/')->with('flash_message', 'Post Deleted!');
    }

    public function create() {
      return view('posts.create');
    }

    public function store(PostRequest $request) {
      $post = new Post();
      $post->title = $request->title;
      $post->body = $request->body;
      $post->save();
      return redirect('/')->with('flash_message', 'Post Added!');
    }

    public function update(PostRequest $request, $id) {
      $post = Post::findOrFail($id);
      $post->title = $request->title;
      $post->body = $request->body;
      $post->save();
      return redirect('/')->with('flash_message', 'Post Updated!');
    }

}
```

```/var/www/html/myblog/app/Http/Controllers/CommentsController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

//追加
use App\Comment;
use App\Post;

class CommentsController extends Controller
{
    //
    public function store(Request $request, $postId) {
      $this->validate($request, [
        'body' => 'required'
      ]);

      $comment = new Comment(['body' => $request->body]);
      $post = Post::findOrFail($postId);
      $post->comments()->save($comment);

      return redirect()
             ->action('PostsController@show', $post->id);
    }

    public function destroy($postId, $commentId) {
      $post = Post::findOrFail($postId);
      $post->comments()->findOrFail($commentId)->delete();
      return redirect()
             ->action('PostsController@show', $post->id);
    }
}
```

##view
 create.blade.php
 edit.blade.php
 index.blade.php
 show.blade.php
 default.blade.php

```/var/www/html/myblog/resources/views/posts/create.blade.php

@extends('layouts.default')

@section('title', 'Add New')

@section('content')
<h1>
  <a href="{{ url('/') }}" class="pull-right fs12">Back</a>
  Add New
</h1>
<form method="post" action="{{ url('/posts') }}">
  {{ csrf_field() }}
  <p>
    <input type="text" name="title" placeholder="title" value="{{ old('title') }}">
    @if ($errors->has('title'))
    <span class="error">{{ $errors->first('title') }}</span>
    @endif
  </p>
  <p>
    <textarea name="body" placeholder="body">{{ old('body') }}</textarea>
    @if ($errors->has('body'))
    <span class="error">{{ $errors->first('body') }}</span>
    @endif
  </p>
  <p>
    <input type="submit" value="Add New">
  </p>
</form>
@endsection
```

```/var/www/html/myblog/resources/views/posts/edit.blade.php

@extends('layouts.default')

@section('title', 'Edit Post')

@section('content')
<h1>
  <a href="{{ url('/') }}" class="pull-right fs12">Back</a>
  Edit Post
</h1>
<form method="post" action="{{ url('/posts', $post->id) }}">
  {{ csrf_field() }}
　　　　<!-- patchメソッドで渡す -->
  {{ method_field('patch') }}
  <p>
    <input type="text" name="title" placeholder="title" value="{{ old('title', $post->title) }}">
    @if ($errors->has('title'))
    <span class="error">{{ $errors->first('title') }}</span>
    @endif
  </p>
  <p>
    <textarea name="body" placeholder="body">{{ old('body', $post->body) }}</textarea>
    @if ($errors->has('body'))
    <span class="error">{{ $errors->first('body') }}</span>
    @endif
  </p>
  <p>
    <input type="submit" value="Update">
  </p>
</form>
@endsection
```

```/var/www/html/myblog/resources/views/posts/index.blade.php

@extends('layouts.default')

@section('title', 'Blog Posts')

@section('content')
<h1>
  <a href="{{ url('/posts/create') }}" class="pull-right fs12">Add New</a>
  Posts
</h1>
<ul>
  @forelse ($posts as $post)
  <li>
    <a href="{{ action('PostsController@show', $post->id) }}">{{ $post->title }}</a>
    <a href="{{ action('PostsController@edit', $post->id) }}" class="fs12">[Edit]</a>
    <form action="{{ action('PostsController@destroy', $post->id) }}" id="form_{{ $post->id }}" method="post" style="display:inline">
    {{ csrf_field() }}
    {{ method_field('delete') }}
      <a href="#" data-id="{{ $post->id }}" onclick="deletePost(this);" class="fs12">[x]</a>
    </form>
  </li>
  @empty
  <li>No posts yet</li>
  @endforelse
</ul>

<script>
function deletePost(e) {
  'use strict';

  if (confirm('are you sure?')) {
    document.getElementById('form_' + e.dataset.id).submit();
  }
}
</script>
@endsection
```

```/var/www/html/myblog/resources/views/posts/show.blade.php

@extends('layouts.default')

@section('title', 'Blog Detail')

@section('content')
<h1>
  <a href="{{ url('/') }}" class="pull-right fs12">Back</a>
  {{ $post->title }}
</h1>

<!-- {!! !!}　　中身をエスケープしないで表示する
nl2br　　　http://php.net/manual/ja/function.nl2br.php
eヘルパー　エスケープする(e関数は指定された文字列にhtmlentitesを実行)
 -->
<p>{!! nl2br(e($post->body)) !!}</p>

<h2>Comments</h2>
<ul>
  @forelse ($post->comments as $comment)
  <li>
    {{ $comment->body }}
    <form action="{{ action('CommentsController@destroy', [$post->id, $comment->id]) }}" id="form_{{ $comment->id }}" method="post" style="display:inline">
    {{ csrf_field() }}
    {{ method_field('delete') }}
      <a href="#" data-id="{{ $comment->id }}" onclick="deleteComment(this);" class="fs12">[x]</a>
    </form>
  </li>
  @empty
  <li>No comment yet</li>
  @endforelse
</ul>

<h2>Add New Comment</h2>
<form method="post" action="{{ action('CommentsController@store', $post->id) }}">
  {{ csrf_field() }}
  <p>
    <input type="text" name="body" placeholder="body" value="{{ old('body') }}">
    @if ($errors->has('body'))
    <span class="error">{{ $errors->first('body') }}</span>
    @endif
  </p>
  <p>
    <input type="submit" value="Add Comment">
  </p>
</form>

<script>
function deleteComment(e) {
  'use strict';

  if (confirm('are you sure?')) {
    document.getElementById('form_' + e.dataset.id).submit();
  }
}
</script>
@endsection
```

```/var/www/html/myblog/resources/views/layouts/default.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>@yield('title')</title>
  <link rel="stylesheet" href="/css/styles.css">
</head>
<body>
  @if (session('flash_message'))
  <div class="flash_message" onclick="this.classList.add('hidden')">{{ session('flash_message') }}</div>
  @endif
  <div class="container">
    @yield('content')
  </div>
</body>
</html>
```

##css
 styles.css

```/var/www/html/myblog/public/css/styles.css

body {
  margin: 0;
  padding: 0;
  font-size: 16px;
  font-family: Verdana, sans-serif;
}

.container {
  width: 380px;
  margin: 0 auto;
}

h1 {
  font-size: 16px;
  border-bottom: 1px solid #ccc;
  padding-bottom: 5px;
}

ul > li {
  padding: 3px 0;
}

.pull-right {
  float: right;
}

.fs12 {
  font-size: 12px;
  font-weight: normal;
}

input[type=text] {
  width: 200px;
  padding: 5px;
}

input[type=submit] {
  width: 100px;
}

textarea {
  padding: 5px;
  width: 350px;
  height: 80px;
}

.hidden {
  display: none;
}

.flash_message {
  text-align: center;
  padding: 5px;
  color: green;
  background: Lavender;
}

.error {
  font-size: 12px;
  color: tomato;
  padding: 3px 0;
  display: block;
}

h2 {
  font-size: 16px;
}
```

##validation
 PostRequest.php

```/var/www/html/myblog/app/Http/Requests/PostRequest.php

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;

class PostRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // return false;
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
          'title' => 'required|min:3',
          'body' => 'required'
        ];
    }
}
```

```php

//名前空間追加
use App\Http\Requests\PostRequest;


```

##config
 app.php
 database.php

```/var/www/html/myblog/config/app.php

'timezone' => 'Asia/Tokyo',

'locale' => 'ja',
```

```/var/www/html/myblog/config/database.php

//省略
```