我很难用Laravel 5做到这一点。但是,在Rails中,我可以很容易地做到这一点:
用户可以是许多团队的一部分。我们知道表User
和Team
没有关系ID,所以我不会在这里发布这些模式,而是我有一个TeamUser
表:
Schema::create('team_users', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('team_id');
$table->timestamps();
});
TeamUser.php:
public function user()
{
return $this->belongsTo(User::class);
}
public function team()
{
return $this->belongsTo(Team::class);
}
Team.php
public function users()
{
return $this->hasManyThrough(User::class, TeamUser::class);
}
user.php的
public function teams()
{
return $this->hasManyThrough(Team::class, TeamUser::class);
}
好像laravel的doc和我见过的其他教程是不同的。我是Laravel的新手,我需要这个设置。
廷克:
$tu = App\TeamUser::create([ 'user_id' => 1, 'team_id' => 1 ]);
Illuminate \ Database \ Eloquent \ MassAssignmentException,带有消息' user_id'
预期:
$tu->users // is_array($tu) to be true
有人可以解释一下这里有什么问题吗?非常感谢。
答案 0 :(得分:1)
据我所知,hasManyThrough()
仅代替链接2 hasMany
关系。在您的情况下,我们必须处理单个many-to-many关系,该关系是通过在所涉及的两个模型上使用belongsToMany()
来定义的。
为此,您应该创建一个连接表。在Laravel中,连接表的命名约定是涉及的两个模型的名称,单数, snake_cased ,并按字母顺序排列,并以_
分隔。在这种情况下,表名称为team_user
。
您需要通过工匠CLI创建迁移:
$ php artisan make:migration create_team_user_pivot_table
并将以下内容放在up()
中为您创建的新类的down()
和YOUR_PROJECT/database/migrations/
方法中。
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('team_user', function (Blueprint $table) {
$table->integer('team_id')->unsigned()->index();
$table->foreign('team_id')->references('id')->on('teams')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['team_id', 'user_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('team_user');
}
完成所有设置后,您可以使用以下控制台命令运行新迁移:
$ php artisan migrate
然后,在您的Team
模型中:
public function users()
{
return $this->belongsToMany(User::class);
}
并在您的User
模型中:
public function teams()
{
return $this->belongsToMany(Team::class);
}
这应该是让关系运作所需的一切。
请注意,没有什么可以阻止您创建名为TeamUser
的额外模型来直接访问您的数据透视/联接表。您必须将该模型中的表名指定为team_user
,因为Eloquent假定表名为模型名称的多个蛇形版本:team_users
。这很简单:
protected $table = 'team_user';
但是,如果额外表的唯一目的是存储关系,我不明白为什么为该表定义Model类可以被认为是有用的。 Laravel附带a bunch of extra features that let you define and access additional columns on join tables through relationships.
(向下滚动一点在数据透视表上保存其他数据)
答案 1 :(得分:0)
为避免看到粘贴的错误消息,您必须将以下行添加到TeamUser.php类中:
protected $fillable = ['user_id', 'team_id'];
答案 2 :(得分:0)
您可以使用belongsToMany
例如在 Team.php :
中public function users() {
return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id');
}
在这种情况下,您不需要创建模型 TeamUser
答案 3 :(得分:0)
在解决雄辩关系时我所做的就是大声说出来:
这表示您需要many-to-many
关系。那么,我们在User.php
中做了什么:
public function teams() {
return $this->belongsToMany(Team::class);
}
然后,在我们Team.php
中,我们这样做;
public function users() {
return $this->hasMany(Users::class);
}
这应该会自动生成一个数据透视表,并将您设置为可以请求的位置,例如用户团队:Users::find(1)->teams
。 请注意,我没有使用括号,因为我想要结果,而不是查询构建器对象。