Laravel 5.1(5) MongoDB多重Eloquent Relationship実践

準備:テスト用コレクション情報

まず、テスト用のコレクション(例)を用意します。

概要

・Collection種別は、上位から病院コレクション(hospitals)→診療科別コレクション(categories)→病気コレクション(diseases)
・Relatonship種別は、1:Mタイプ、親collectionの場合hasMany、子コレクションの場合belongsToに指定する
・Relatonship紐づけは、_id、category_id、disease_idに指定する、他デフォルト利用の場合もある

コレクションの構造と内容

$hospitals = App\Hospital::all()
=> Illuminate\Database\Eloquent\Collection {#977
     all: [
       App\Hospital{#999
         _id: MongoDB\BSON\ObjectId {#976
           +"oid": "5a7d0901f1a5e421d37a12e2",
         },
         name: "hospi",
         created_at: "2018-01-16 02:01:03",
         updated_at: MongoDB\BSON\UTCDateTime {#975
           +"milliseconds": "1518231495000",
         },
       },
    ],
   }
$categories = App\Category::all()
=> Illuminate\Database\Eloquent\Collection {#977
     all: [
       App\Category {#999
         _id: MongoDB\BSON\ObjectId {#976
           +"oid": "5a7d0901f1a5e421d37daac2",
         },
         hospital_id: "5a7d0901f1a5e421d37a12e2",
         name: "Nerve",
         created_at: "2018-01-16 02:01:03",
         updated_at: MongoDB\BSON\UTCDateTime {#975
           +"milliseconds": "1518231495000",
         },
       },
    ],
   }
$diseases = App\Disease::all()
=> Illuminate\Database\Eloquent\Collection {#977
     all: [
       App\Disease{#999
         _id: MongoDB\BSON\ObjectId {#976
           +"oid": "5a7d0901f1a5e421d37d090d0",
         },
         category_id: "5a7d0901f1a5e421d37daac2",
         name: "Cerebral Bleeding",
         created_at: "2018-01-16 02:01:03",
         updated_at: MongoDB\BSON\UTCDateTime {#975
           +"milliseconds": "1518231495000",
         },
       },
    ],
   }

Model構築

以下ソースにコメント割愛とします。

Hospital Model

class Hospital extends Eloquent
{
    protected $collection = 'hospitals';
    protected $connection = 'mongodb';
    protected $fillable = ['name' , 'description'];
    public function categories() 
    {
        return $this->hasMany('App\Category', 'hospital_id', '_id');
    }
}

Category Model

class Category extends Eloquent
{
    protected $collection = 'categories';
    protected $connection = 'mongodb';
    protected $fillable = ['hospital_id' , 'name' , 'description'];
    public function hospital() 
    {
        return $this->belongsTo('App\Hospital','hospital_id', '_id');
    }
    public function diseases() 
    {
        return $this->hasMany('App\Disease','category_id', '_id');
    }
}

Disease Model

class Diease extends Eloquent
{
    protected $collection = 'diseases';
    protected $connection = 'mongodb';
    protected $fillable = ['categoy_id' , 'name' , 'description'];
    public function category() 
    {
        return $this->belongsTo('App\Category','category_id', '_id');
    }
}

Collection作成

hospitals Collection

class CreateHospitalsCollection extends Migration
{
    public function up()
    {
        Schema::create('hospitals', function (Blueprint $collection) {
            $collection->string('name');
            $collection->string('description');
            $collection->timestamps();

         });
    }
    public function down()
    {
        Schema::drop('hospitals');
    }

categories Collection

class CreateCategoriesCollection extends Migration
{
    public function up()
    {
        Schema::create('categories', function (Blueprint $collection) {
            $collection->string('hospital_id');
            $collection->string('name');
            $collection->string('description');
            $collection->timestamps();
            $collection->foreign('hospital_id')
                       ->references('_id')
                       ->on('hospitals')
                       ->onDelete('cascade');
         });
    }
    public function down()
    {
        Schema::drop('categories');
    }

diseases Collection

class CreateDiseasesCollection extends Migration
{
    public function up()
    {
        Schema::create('diseases', function (Blueprint $collection) {
            $collection->string('category_id');
            $collection->string('name');
            $collection->string('description');
            $collection->timestamps();
            $collection->foreign('category_id')
                       ->references('_id')
                       ->on('categories')
                       ->onDelete('cascade');
         });
    }
    public function down()
    {
        Schema::drop('diseases');
    }

・DBに反映する。

composer dump-autoload
php artisan migrate:refresh --seed

Relationship検証

上位→下位の順にて参照また下位→上位の順にて参照

$ php artisan tinker

hospital→categories

>>>$hospitals = App\Hospital::all()
>>>$hospitals= hospitals->first()
>>>$category= $hospital->categories->first()

category->hospital

>>>$categories = App\Category::all()
>>>$category = $categories->first()
>>>$hospital = $category->hospital

category->disease

>>>$categories = App\Category::all()
>>>$category = $categories->first()
>>>$diseases = $category->diseases

disease->category

>>>$diseases = App\Disease::all()
>>>$disease = $diseases->first()
>>>$category = $disease->category

hospital→diseases

>>>$hospitals = App\Hospital::all()
>>>$hospital  = hospitals->first()
>>>$diseases = $hospital->categories->first()->diseases

disease->hospital

>>>$diseases = App\Disease::all()
>>>$disease = $diseases->first()
>>>$hospital= $disease->category->hospital

$hospital、$category、$diseaseがうまく表示されたら、紐付けができたことが検証済み。
Null、Errorが表示された場合、どこかで入力ミスあるか確認する。

上位から紐づけまた下位から紐づけして保存

>>>$hospital->categorys()->save($category)
>>>$category->diseases()->save($disease)

>>>$category->hospital()->associate($hospital)
>>>$disease->category()->associate($category)

以上。

研究開発・検証試作に提案するロボット翔・電子部品ストアロボット、センサ、通信モジュールが品揃えています。どうぞご利用下さい