在 Laravel 中迁移外键与雄辩的关系

Posted

技术标签:

【中文标题】在 Laravel 中迁移外键与雄辩的关系【英文标题】:Migration Foreign Key Vs Eloquent Relationships in Laravel 【发布时间】:2015-09-29 03:03:57 【问题描述】:

在 Laravel 5.1 中,我可以看到表列关系可以通过两种方式设置:

1) 在迁移表中定义外键。

2) 在模型中定义 Eloquent 关系。

我已阅读文档,但我仍然对以下内容感到困惑:

    我需要同时使用还是只需要 1 个?

    两者同时使用有错吗?还是成功了 冗余或引起冲突?

    使用 Eloquent 关系而不提及 迁移列中的外键?

    有什么区别?

这些是我现在拥有的代码。如果我需要删除我在迁移文件中设置的外键,我仍然不清楚。

迁移:

  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');
     

有人可以帮我理解一下吗?

【问题讨论】:

【参考方案1】:

两者齐头并进。一个是不完整的,没有另一个。如果你想让你的关系正常工作,你需要定义这两个东西。

如果您刚刚在迁移文件中定义了外键,那么该关系将在您编写原始查询时起作用。它不适用于您的模型,因为您没有在模型中编写任何有关关系的内容。

所以,只要您在其中一个模型中写入hasMany,并在另一个模型中写入相应的函数,您的模型才会相互了解,然后您就可以通过您的模型以及在你的数据库。

另请注意,如果您在模型中通过hasManybelongsTo 正确定义了关系,但没有在belongsTo 其他表的模型表中提供外键,则您的关系将不起作用.

简而言之,两者都是强制性的。

【讨论】:

完美。这就是我感到困惑的地方,感谢您为我确认。快速查看上面的迁移和模型代码,我是否正确完成了关系和外键约束的互连?这是我的第一次尝试,只是想知道我是否走在正确的道路上。再次感谢@ArslanAli @Neel 对于您的代码审查,您可以将您的代码发布到codereview.stackexchange.com,并且可以获得一个体面的(我希望)审查。谢谢。 我编辑了我的答案。对不起。好吧,我的意思是,如果您不在迁移文件中提供integer('user_id'),而只是在模型中写入belongsTo,它将无法正常工作。 我知道这是一个旧答案,但不确定自那以后是否有任何变化。我已经在我的模型中声明了关系,但没有在 mogrations 中完成外键约束,但我的东西仍然运作良好。 Eloquent 假定列的名称(例如 app_id 等)。在这种情况下 - 是否需要在 mogrations 中指定外键?如果我还是声明它会给我的应用添加什么? @Varin 我知道这是一篇旧帖子,为了回答您的问题,是的,我在模型中声明了关系,而没有在迁移文件中使用外键,它工作得很好。因此,我认为它是可选的。【参考方案2】:

Eloquent 根据模型名称假设关系的外键。在这种情况下,App 模型被自动假定为具有 app_id 外键,因此在您的迁移中您无需指定:

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

Documentation

【讨论】:

以上是关于在 Laravel 中迁移外键与雄辩的关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 雄辩的关系有很多两个外键错误

如何在 Laravel 雄辩关系中添加多个条件

laravel 雄辩 hasOneThrough 外键

Laravel 8.X Eloquent 中数据库迁移的正确外键约束语法是啥?

Laravel 5.6 |雄辩的一对多关系

laravel 雄辩的关系 3 模型