laravelでただ純粋に下記のようなSQL文の結果を出力したい!!
SELECT *
FROM parentTables
JOIN childTables
ON parentTables.cld_id = childTables.id
しかし色々調べても、まどろっこしい説明が多くどこに何を書けばいいのかわからなかった。自分のような迷える子羊を救いたいので説明していく。
前提条件
既にマイグレーションファイルがあり、テーブルが作成されていて、
ModelとControllerのファイルが作成されていることを前提に話を進めていく。
今回は例としてparentTablesテーブルとchildTablesテーブルを使用する。
その場合、上記のそれぞれのファイルは下記の場所にある。(xは数字が入る)
- database/migrations/xxxx_xx_xx_xxxxxxx_create_parentTables_table.php
- database/migrations/xxxx_xx_xx_xxxxxxx_create_childTables_table.php
- app/Models/ParentTable.php
- app/Models/ChildTable.php
- app/Http/Controllers/ParentTableController.php
- app/Http/Controllers/ChildTableController.php
そして、それぞれのテーブルには下記のようなデータが入っているとする。
parentTablesテーブル
+------+--------+----------+
| id |cld_id |name |
+------+--------+----------+
| 1 | 1 | 田中 |
| 2 | 1 | 山田 |
| 3 | 2 | 中田 |
+------+--------+----------+
childTablesテーブル
+------+----------+
| id |name |
+------+----------+
| 1 | 赤 |
| 2 | 白 |
+------+----------+
出力データはresources/views/test.blade.phpにデータを渡して表示をするようにする。
DBの処理方法は2種類ある
DBクラス(クエリビルダ)を使用する方法と、Eloquent(ORM)を使用する方法
DBクラス(クエリビルダ)を使用する場合
app/Models/ParentTable.phpのクラス内にprotected $table = 'parentTables';を
追加する
//app/Models/ParentTable.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ParentTable extends Model
{
~~
protected $table = 'parentTables'; //この文を加える
}
app/Models/ChildTable.phpのクラス内にprotected $table = 'childTables';を
追加する
//app/Models/ChildTable.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ChildTable extends Model
{
~~
protected $table = 'childTables'; //この文を加える
}
どのコントローラーでも良いが、今回はParentTableControllerのindex関数に
処理を記載して、test.blade.phpにデータを渡す。
※ 文頭でuse Illuminate\Support\Facades\DB;を加えることが必要
//app/Http/Controllers/ParentTableController.php
use Illuminate\Support\Facades\DB; //この文を加える
~~
public function index()
{
$tableDatas = DB::table('parentTables as p')
->join('childTables as c', 'p.cld_id', '=', 'c.id')
->select('p.id as id_p','p.name as name_p','c.name as name_c')
->get();
return view('test', ['tableDatas' => $tableDatas]);
}
~~
※ parentTablesとchildTablesに同名のカラム名(name)があるので、as ~で別名に
する必要がある。
resources/views/test.blade.phpでデータを表示
//resources/views/test.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Your Page</title>
</head>
<body>
<p>出力結果</p>
@foreach ($tableDatas as $data)
<p>{{ $data->id_p }}番の{{ $data->name_p }}さんは{{ $data->name_c }}</p>
@endforeach
</body>
/*
出力結果
1番の田中さんは赤
2番の山田さんは赤
3番の中田さんは白
*/
Eloquent(ORM)を使用する場合
Eloquentリレーションシップを使用して、異なるテーブル間のリレーションを定義する。
方法は下記の通り。今回はhasOne関数を使用。
外部キーを持っているテーブルのモデルに関数を定義して、hasOne関数を使用する。
joinでくっつく方のテーブルのモデルに関数を定義して、belongsTo関数を使用する。
hasOne関数の第一引数は相手のクラス、第二引数は外部キー、第三引数はくっつく
方のテーブルの主キー(主キー以外でも可)
belongsTo関数の第一引数は相手のクラス、第二引数は外部キー、第三引数はくっつく方のテーブルの主キー(主キー以外でも可)
どちらの関数も第二、第三の引数は同じ記述なので注意が必要。
今回の例の場合は下記のようになる。
app/Models/ParentTable.php
//app/Models/ParentTable.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ParentTable extends Model
{
~~
//下記の関数を定義
public function relatedChildTable()
{
return $this->hasOne(ChildTable::class, 'cld_id', 'id');
}
}
app/Models/ChildTable.php
//app/Models/ChildTable.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ChildTable extends Model
{
~~
//下記の関数を定義
public function relatedParentTable()
{
return $this->belongTo(ParentTable::class, 'cld_id', 'id');
}
}
どのコントローラーでも良いが、今回はParentTableControllerのindex関数に
処理を記載して、test.blade.phpにデータを渡す。
文頭でuse Illuminate\Support\Facades\DB;を加えることが必要
//app/Http/Controllers/ParentTableController.php
use App\Models\ParentTable
~~
public function index()
{
$tableDatas = ParentTable::with('relatedChildTable')->get();
return view('test', ['tableDatas' => $tableDatas]);
}
~~
resources/views/test.blade.phpでデータを表示
//resources/views/test.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Your Page</title>
</head>
<body>
<p>出力結果</p>
@foreach ($tableDatas as $data)
<p>{{ $data->id }}番の{{ $data->name }}さんは{{ $data->relatedChildTable->name }}</p>
@endforeach
</body>
/*
出力結果
1番の田中さんは赤
2番の山田さんは赤
3番の中田さんは白
*/
Eloquent(ORM)を使用している場合は$data->relatedChildTableで、くっついた側のchildTablesテーブルの値を取得できる。
色々と調べてまとめてみましたが間違っている部分がある可能性があります。
間違ってたらごめんなさい。
また、hasOne関数ではなくhasMany関数を使う場合があったりとlaravelのDBの処理
は奥が深い。(実はまだしっかりと理解できていないのは内緒)
この記事はあくまで参考程度にして、この記事の情報だけに頼らず色々調べた方が良いです。