PHP
laravel

Laravelでモデル作成

Laravel初見なので個人的メモです。

LaravelディレクトリメモでDB設定をした続き

1.モデルの作成

Postモデルを作成
バージョン管理するためのマイグレーションファイルも作成するため --migrationオプションをつける

php artisan make:model Post --migration 実行

マイグレーションファイルの中身を確認

<?php

use Illuminate\Support\Facades\Schema;
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) {
      // postsという複数形のテーブルが作成されており、
      // Railsのようにidとtimestampsが作成されている
            $table->increments('id');
            $table->timestamps();
        });
    }

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

コード内にup()とdown()というメソッドがあるのだが、
up()がこのマイグレーションで行いたい処理
down()がそれを巻きもどすための処理 になります。

Railsのようにidとtimestampsが自動生成されており、ここに追加することでカラムを追加できる

database/migrations/XXXXX.php
カラムの追加
$table->increments('id');
$table->string('title');  #string型のtitleカラムを追加
$table->text('body');  #text型のbodyカラムを追加
$table->timestamps();

では、migrationファイルを実行していく

php artisan migrate

上手くいってなかったり、間違えて1つ前のマイグレーションへ戻す場合はこちらを実行

php artisan migrate:rollback 
$ php artisan migrate
Migration table created successfully.
Migrating: 2018_05_13_135622_create_posts_table
Migrated:  2018_05_13_135622_create_posts_table

この時点で作成した、database.sqliteファイルが更新されている

今回はDBにsqliteを使うので
sqliteでアクセスしてテーブルが作成されているか確認.

sqlite3 database/作成したdbファイル名.sqliteを実行
(mysqlの場合はmysqlのファイル名を入れてあげる)

今回作成したのは、database.sqliteなので下記コードを実行:

sqlite3 database/database.sqlite
sqlite> .schema posts 実行

CREATE TABLE IF NOT EXISTS "posts" ("id" integer not null primary key autoincrement, "title" varchar not null, "body" text not null, "created_at" datetime null, "updated_at" datetime null);

正しくtitleとbodyカラムが作成されていることを確認!

一旦sqliteから抜ける

.exit

2.インタラクティブにModelを操作(コンソール操作)

まずは「php artisan tinker」でコンソールを立ち上げる
(Railsでのrails consoleと同じイメージ)

$ php artisan tinker

Psy Shell v0.9.3 (PHP 7.2.5 — cli) by Justin Hileman
>>> 

・レコードに挿入してみる

まずはインスタンスを作成し、saveメソッドを使ってみます。
名前空間がデフォルトでAppになっているのでApp\Post();としてあげる

>>> $post = new App\Post();
=> App\Post {#2283}
>>> 

インスタンスの作成完了!

postのtitleを「title 1」bodyを「body 1」という様に保存してみる

>>> $post->title = 'title 1'; #title 1を格納
=> "title 1" 
>>> $post->body = 'body 1';  #body 1を格納
=> "body 1"
>>> $post->save(); #これらの変更を保存
=> true #成功
>>> 

保存したデータを確認

App\Post::all();

実行結果
=> Illuminate\Database\Eloquent\Collection {#2291
     all: [
       App\Post {#2292
         id: "1",
         title: "title 1",
         body: "body 1",
         created_at: "2018-05-13 14:52:59",
         updated_at: "2018-05-13 14:52:59",
       },
     ],
   }

Railsでいう Model名.allと同じと解釈
(User.all, Post.all等)

【配列で取り出したい場合】
また配列で取り出したい場合は->ToArray();を指定してあげれば良い
これでスッキリとした構造で返ってくる

>>> App\Post::all()->ToArray();

実行結果
=> [
     [
       "id" => 1,
       "title" => "title 1",
       "body" => "body 1",
       "created_at" => "2018-05-13 14:52:59",
       "updated_at" => "2018-05-13 14:52:59",
     ],
   ]

一旦tinkerを抜けてsqliteでも確認してみる

exit
$ sqlite3 database/database.sqlite
sqlite> select * from posts;

実行結果:
1|title 1|body 1|2018-05-13 14:52:59|2018-05-13 14:52:59

正しく保存されていることを確認できた!

確認だけなので.exitで抜けておく

とりあえずこれでモデルの作成とデータの操作は問題なさそう

・追加(create)

newでは無く、createすることで一発で作成と保存も可能
これもRailsと同じ

App\Post::create(['title' => 'title 2', 'body' => 'body 2']);

ただLaravelの場合このままcreateしようとするとマスアサイメントエラー?になってしまう為、一手間必要。
(MassAssignment: MassAssignmentは意図しないリクエストによって悪意のあるデータが挿入されてしまう脆弱性のこと)という事らしい。

モデルの設定を追加する必要があるのでapp/Post.phpを開く

protected $fillable とした後に、この column にはデータを挿入してもいいよという設定を追加します。

app/Post.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
    protected $fillable = ['title', 'body']; この部分を追加
}

これでtitleとbodyにデータの挿入ができる様になりました.

tinkerを再起動してcreateしてみる

>>> App\Post::create(['title' => 'title 2', 'body' => 'body 2']);

=> App\Post {#2281
     title: "title 2",
     body: "body 2",
     updated_at: "2018-05-13 15:35:28",
     created_at: "2018-05-13 15:35:28",
     id: 2,
   }

   create成功!!

App\Post::all();してみる

>>> App\Post::all();
=> Illuminate\Database\Eloquent\Collection {#2293
     all: [
       App\Post {#2294
         id: "1",
         title: "title 1",
         body: "body 1",
         created_at: "2018-05-13 14:52:59",
         updated_at: "2018-05-13 14:52:59",
       },
       App\Post {#2295
         id: "2",
         title: "title 2",
         body: "body 2",
         created_at: "2018-05-13 15:35:28",
         updated_at: "2018-05-13 15:35:28"

はい、OK