Laravel 5.4: Eloquent ORMを使ってみる

What?

  • Eloquent ORM: Laravel5にデフォルトで組み込まれているORマッパー
  • RailsのActive Recodeみたいに使える

How to

DBにモデルを保存

  • モデルを作る -> app/Article.php ができている
$ php artisan make:model Article
$ cat app/Article.php
<?php namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class Article extends Model {
 
    //
 
}
  • モデルができているかtinkerで確認
$ php artisan tinker

>>> $article = new App\Article;                                                                      => App\Article {#668}
  • モデルを使う (オブジェクトを作って、値を入れる)
>>> $article = new App\Article;
=> App\Article {#673}
>>> $article->title = 'My First Article';
=> "My First Article"
>>> $article->body = 'Lorem ipsum';
=> "Lorem ipsum"
>>> $article->published_at = Carbon\Carbon::now();
=> Carbon\Carbon {#682
     +"date": "2017-03-04 11:53:09.134952",
     +"timezone_type": 3,
     +"timezone": "UTC",
   }
>>> $article;
=> App\Article {#673
     title: "My First Article",
     body: "Lorem ipsum",
     published_at: Carbon\Carbon {#682
       +"date": "2017-03-04 11:53:09.134952",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
   }
  • 作ったオブジェクトをセーブする
>>> App\Article::all()->toArray();
=> []
>>> $article->save();
=> true
>>> App\Article::all()->toArray();
=> [
     [
       "id" => 1,
       "title" => "My First Article",
       "body" => "Lorem ipsum",
       "created_at" => "2017-03-04 11:53:44",
       "updated_at" => "2017-03-04 11:53:44",
       "published_at" => "2017-03-04 11:53:09",
     ],
   ]
$ mysql --user=homestead --password=secret homestead
mysql> select * from articles\G;
*************************** 1. row ***************************
          id: 1
       title: My First Article
        body: Lorem ipsum
  created_at: 2017-03-04 11:53:44
  updated_at: 2017-03-04 11:53:44
published_at: 2017-03-04 11:53:09
1 row in set (0.00 sec)

DBからモデルを読み込みアップデートしてみる

  • tinker でDBから情報を1行読み込んで、更新後、セーブする
>>> $article = App\Article::all()->first();
=> App\Article {#689
     id: 1,
     title: "My First Article",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 11:53:44",
     published_at: "2017-03-04 11:53:09",
   }
>>> $article->title = 'My First Article Updated';
=> "My First Article Updated"
>>> $article->save();                                                                                => true
  • DBを確認
mysql> select * from articles\G;
*************************** 1. row ***************************
          id: 1
       title: My First Article Updated
        body: Lorem ipsum
  created_at: 2017-03-04 11:53:44
  updated_at: 2017-03-04 12:09:32
published_at: 2017-03-04 11:53:09
1 row in set (0.00 sec)

色々な方法でデータを検索する

>>> App\Article::find(1);
=> App\Article {#684
     id: 1,
     title: "My First Article Updated",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 12:09:32",
     published_at: "2017-03-04 11:53:09",
   }
>>> App\Article::where('body', 'Lorem ipsum')->get();
=> Illuminate\Database\Eloquent\Collection {#656
     all: [
       App\Article {#692
         id: 1,
         title: "My First Article Updated",
         body: "Lorem ipsum",
         created_at: "2017-03-04 11:53:44",
         updated_at: "2017-03-04 12:09:32",
         published_at: "2017-03-04 11:53:09",
       },
     ],
   }
>>> App\Article::where('body', 'Lorem ipsum')->first();
=> App\Article {#693
     id: 1,
     title: "My First Article Updated",
     body: "Lorem ipsum",
     created_at: "2017-03-04 11:53:44",
     updated_at: "2017-03-04 12:09:32",
     published_at: "2017-03-04 11:53:09",
   }

createメソッドを使ってみる

  • createメソッドはまとめて値を入力できるので便利

    • ただし、ユーザの突っ込んできた値の全てを受け入れると危険
    • $fillableで、createでアサインできる値のホワイトリストを指定できる
    • $guardedで、createでアサインできる値のブラックリストを指定できる
  • App\Article::create()でまとめて作ろうとするとMassAssignmentExceptionエラーが出る

>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
  • app/Article.phpモデルを修正する
<?php namespace App;
 
use Illuminate\Database\Eloquent\Model;
 
class Article extends Model {
 
    protected $fillable = [ // 
        'title',
        'body',
        'published_at'
    ];
 
}
  • ん?まだ、MassAssignmentExceptionエラーが出る
>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
Illuminate\Database\Eloquent\MassAssignmentException with message 'title'
  • tinkerを立ち上げなおしてリトライ。できた。
>>> $article = App\Article::create(['title' => 'New Article', 'body' => 'Lorem ipsum', 'published_at' => Carbon\Carbon::now()]);
=> App\Article {#670
     title: "New Article",
     body: "Lorem ipsum",
     published_at: Carbon\Carbon {#661
       +"date": "2017-03-04 12:17:28.029855",
       +"timezone_type": 3,
       +"timezone": "UTC",
     },
     updated_at: "2017-03-04 12:17:28",
     created_at: "2017-03-04 12:17:28",
     id: 2,
   }

参考