8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravelで簡単なメモアプリを作る(2)~データの取得と保存~

Last updated at Posted at 2020-01-03

はじめに

Laravelとは、Webに特化したPHPフレームワーク。セキュリティ対策(CSRF対策など)もこれでできます。MVCアーキテクチャを採用しています。今回は、データベースの接続とデータの取得と保存をしていきたいと思います。

Laravelで簡単なメモアプリを作る(1)~Viewの作成と表示~
Laravelで簡単なメモアプリを作る(3)~データの更新と削除~

今回の目標物

スクリーンショット 2019-12-31 11.25.14.png スクリーンショット 2019-12-31 11.25.26.png

データ取得の流れ

スクリーンショット 2020-01-01 19.00.07.png スクリーンショット 2020-01-01 19.00.16.png スクリーンショット 2020-01-01 19.00.23.png

データベースの作成

データベースの作成

phpMyAdminを開く。Newを押して、新しくdatabaseを作成する。今回は、memoAppという名前のデータベースを作成する。

スクリーンショット 2020-01-01 19.05.57.png

データベースの接続

.envに、データベースの情報を記述する。DB_DATABESEには、データベースの名前を入れる。MAMPを使っている人は、デフォルトでユーザー名、パスワード共にrootなので特に設定していなければ、下の内容をそのままコピー&ペーストして良い。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=memoApp
DB_USERNAME=root
DB_PASSWORD=root

モデルの作成

ターミナルまたは、PowerShellを開き、cdコマンドでmemoAppまで移動し、下のコマンドを打ち込む。

$ php artisan make:model Memo

先ほど作成したモデルにDBのテーブル情報を記述する。

app/Memo.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Memo extends Model
{
    // table名を指定
    protected $table = 'memo';

    // カラムを指定
    protected $fillable = [
        'id', 'title', 'content'
    ];

    // created_atを使わない場合はfalseを指定する。
    public $timestamps = false;
}

テーブルの作成

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

ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan make:migration create_memo_table

先ほど、生成したファイルにカラムの情報を記述する。

id : bigInt型
title : string型 24桁
content: string型 60桁

database/migrations/2019_12_12_114638_create_memo_table.php
<?php

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

class CreateMemoTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('memo', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title', 24);
            $table->string('content', 60);
        });
    }

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

seederの作成

ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan make:seeder MemoTableSeeder
database/seeds/MemoTableSeeder.php
<?php

use Illuminate\Database\Seeder;

use App\Memo;

class MemoTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('memo')->delete(); //最初に全件削除

        Memo::create([
            'title' => '12/13 laravel勉強会', 'content' => 'データの読み取りと追加をやりました。'
        ]);

        Memo::create([
            'title' => '12/6 laravel勉強会', 'content' => 'Viewの表示をしました。'
        ]);
    }
}
database/seeds/DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Model::unguard();

        $this->call('MemoTableSeeder');

        Model::reguard();
    }
}

マイグレーションとSeederの反映

phpMyAdminにマイグレーションとSeederを反映させる。ターミナルまたはpowerShellを開いて、cdコマンドでmemoAppまで移動し、下のコマンドを打つ。

$ php artisan migrate --seed

phpMyAdminを開いて、反映されているかどうか確認する。

ちなみに、エクセル形式で表すとこんな感じになる。

スクリーンショット 2020-01-01 19.26.08.png

データの取得

データをViewに渡す

app/Http/Controllers/MemoController.phpに、データをViewに渡すメソッドを記述する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit()
    {
        return view("submit");
    }
}

とりあえずresources/views/home.blade.phpの適当なところに<div>{{$memos}}</div>を入れて、表示を確認してみよう。

$memosの中身が、id,title,contentの要素を持つオブジェクトの配列になっていることがわかる。

スクリーンショット 2020-01-03 15.34.31.png

resources/views/home.blade.phpの適当なところに以下のコードを追加してみる。

<div>{{$memos[0]->id}}</div>
<div>{{$memos[0]->title}}</div>
<div>{{$memos[0]->content}}</div>

ループを使わずにこんな感じで表示してみよう。

スクリーンショット 2020-01-03 15.41.46.png
home.blade.php
<tbody>
  <tr>
    <td class="left">{{$memos[0]->title}}</td>
    <td><a href="{{ route('submit')}}">編集</a></td>
    <td><a>削除</a></td>
  </tr>
  <tr>
    <td class="left">{{$memos[1]->title}}</td>
    <td><a href="{{ route('submit')}}">編集</a></td>
    <td><a>削除</a></td>
  </tr>
</tbody>

これをループを用いて、記述するとこんな感じになる。

resources/views/home.blade.php
<tbody>
   @foreach ($memos as $memo)
     <tr>
       <td class="left">{{$memo->title}}</td>
       <td><a href="{{ route('submit')}}">編集</a></td>
       <td><a>削除</a></td>
     </tr>
   @endforeach
</tbody>

bladeファイルはhtmlファイルと違って、@を使うことで直接、条件分岐やループ文を記述することができる。中括弧で囲む必要がないが@endif@endforなどで閉じてやる必要がある。

詳細画面にもデータを渡す

URLからメモのidを受け取れるようにする。URLを‘/submit/{id?}’にすることで、idという変数をコントローラに渡すことができる。

routes/web.php
<?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('sample');
});

Route::get('/home', 'MemoController@showHome')->name('home');

Route::get('/submit/{id?}', 'MemoController@showSubmit')->name('submit');

リンクを押すと、URLにidを含んだページに飛べるようにする。href="{{ route('submit', ['id' => $memo->id])}}"とすることで、URLにidを渡すことができる。

resources/views/home.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        color: white;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .card {
        margin-top: 40px;
    }

    .left {
        width: 70%;
    }

    .submit {
        position: absolute;
        top: 10px;
        right: 20px;
    }
</style>
@endsection

@section('content')
<div class="card" style="width: 100%;">
    <div class="card-header">
        メモ一覧
        <a href="{{ route('submit')}}" class="submit">メモを追加</a>
    </div>

    <table class="table">
        <tbody>
            @foreach ($memos as $memo)
            <tr>
                <td class="left">{{$memo->title}}</td>
                <td><a href="{{ route('submit', ['id' => $memo->id])}}">編集</a></td>
                <td><a>削除</a></td>
            </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

コントローラーの関数の引数に、URLの変数を渡せる。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }
}

コントローラから送られてきたデータを、Viewに埋め込む。

resources/views/submit.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .container {
        margin-top: 40px;
    }
</style>
@endsection

@section('content')
<form>
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}">
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}">
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    <button type="submit" class="btn btn-success">追加</button>
</form>
@endsection

データの保存

postを使って、データをコントローラに送る。

resources/views/submit.blade.php
@extends('layouts.app')

@section('css')
<style>
    header {
        height: 50px;
        background-color: #000;
        padding-left: 20px;
        font-size: large;
        color: #ddd;
    }

    .title {
        position: absolute;
        top: 10px;
    }

    .container {
        margin-top: 40px;
    }
</style>
@endsection

@section('content')
<form method="POST" action="{{ route('submit', ['id' => $memo->id])}}">
    @csrf
    <div class="form-group">
        <label for="title">タイトル</label>
        <input type="text" class="form-control" id="title" name="title" value="{{$memo->title}}">
    </div>
    <div class="form-group">
        <label for="content">内容</label>
        <input type="text" class="form-control" id="content" name="content" value="{{$memo->content}}">
    </div>
    <a href="{{ route('home')}}" class="btn btn-primary">戻る</a>
    <button type="submit" class="btn btn-success">追加</button>
</form>
@endsection

MemoControllerに、Viewから送られてきたデータをデータベースに保存するメソッドを記述する。

app/Http/Controllers/MemoController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Memo;

class MemoController extends Controller
{
    public function showHome()
    {
        $memos = Memo::get();
        return view("home", ['memos' => $memos]);
    }

    public function showSubmit($id = 0)
    {
        if ($id != 0) {
            $memo = Memo::where('id', $id)->get()->first();
        } else {
            $memo = (object) ["id" => 0, "title" => "", "content" => ""];
        }
        return view("submit", ['memo' => $memo]);
    }

    public function postSubmit(Request $request, $id = 0)
    {
        $title = $request->input('title');
        $content = $request->input('content');
        if ($id == 0) {
            Memo::create([
                'title' => $title,
                'content' => $content
            ]);
        }
        return redirect()->route('home');
    }
}

web.phpに以下の内容を記述する。

routes/web.php
<?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('sample');
});

Route::get('/home', 'MemoController@showHome')->name('home');

Route::get('/submit/{id?}', 'MemoController@showSubmit')->name('submit');

Route::post('/submit/{id?}', 'MemoController@postSubmit')->name('submit');

今回はここまで。次回は、データの編集と削除をしたいと思います。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?