web-dev-qa-db-ja.com

Laravelでの移行外部キーと雄弁な関係

Laravel 5.1では、テーブルの列の関係を2つの方法で設定できることがわかります。

1)移行テーブルでの外部キーの定義

2)モデルでの雄弁な関係の定義。

私はドキュメントを読みましたが、それでも以下について混乱しています:

  1. 両方を使用する必要がありますか、それとも1つだけ必要ですか?

  2. 両方を同時に使用するのは間違っていますか?それとも冗長にするか、競合を引き起こしますか?

  3. 移行列の外部キーに言及せずに雄弁な関係を使用する利点は何ですか?

  4. 違いはなんですか?

これらは私が現在持っているコードです。移行ファイルで設定した外部キ​​ーを削除する必要があるかどうかは、まだわかりません。

移行:

  public function up()
    {   

       Schema::create('apps', function (Blueprint $table) {
          $table->increments('id');
          $table->string('app_name');
          $table->string('app_alias');
          $table->timestamps();
          $table->engine = 'InnoDB';
       });

      // This is the second Migration table
      Schema::create('app_roles', function (Blueprint $table) {
          $table->increments('id');
          $table->integer('app_id')->unsigned()->index();
          $table->integer('user_id')->unsigned()->index();
          $table->integer('role_id')->unsigned()->index();
          $table->engine = 'InnoDB';

          $table->unique(array('app_id', 'user_id'));

          $table->foreign('app_id')
                ->references('id')
                ->on('apps')
                ->onDelete('cascade');

          $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');

          $table->foreign('role_id')
                ->references('id')
                ->on('roles')
                ->onDelete('cascade');
        });     
    }

雄弁な関係を持つモデル:

// App Model
class App extends Model
{

     public function appRoles() {
         return $this->hasMany('App\Models\AppRole');
     }
}

// AppRole Model
class AppRole extends Model
{
   public function app() {
       return $this->belongsTo('App\Models\App');
   }

   public function user() {
       return $this->belongsTo('App\User');
   }

   public function role() {
       return $this->belongsTo('App\Models\Role');
   }
}

// User Model
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    .....
    public function appRole() {
         return $this->belongsToMany('App\Models\AppRole');
     }
}

// Role Model
class Role extends EntrustRole
{
     public function appRole() {
         return $this->hasMany('App\Models\AppRole');
     }
}

誰かがこれを理解するのを手伝ってくれませんか?

28
Neel

どちらも密接に関係しています。片方はもう片方なしで不完全です。関係を適切に機能させるには、これらの両方を定義する必要があります。

移行ファイルで外部キーを定義したばかりの場合、生のクエリを作成する場合に備えてリレーションが機能します。モデルの関係について何も記述していないため、モデルでは機能しません。

したがって、モデルの1つにhasManyを記述し、他のモデルに対応する関数を作成するとすぐに、モデルがお互いを認識し、モデルだけでなく、データベース。

モデルのhasManybelongsToを介して関係を適切に定義しているが、モデルのテーブルに外部キーを提供していない場合は、who [belongsTo other table、あなたの関係は機能しません。

つまり、両方とも同様に強制的です。

29
Arslan Ali

Eloquentは、モデル名に基づいて関係の外部キーを想定します。この場合、Appモデルは自動的にapp_id外部キーなので、移行では以下を指定する必要はありません。

$table->foreign('app_id')
->references('id')
->on('apps')
->onDelete('cascade');

ドキュメント

4
apex39