我必须使用Laravel开发一个api,但我遇到了这个问题: 我需要获取所有匹配项,并且每次匹配都需要获取属于该匹配项的用户(每个匹配项有2个用户)
我已经找到了这个问题的答案,但我发现了这个https://github.com/topclaudy/compoships,但对我没有用。
到目前为止,我有这个:
class Match extends Model
{
protected $table = 'matchs';
public $primaryKey = 'id';
public function playerOne() {
return $this->hasMany('App\User', 'id', 'playerOne_id');
}
public function playerTwo() {
return $this->hasMany('App\User', 'id', 'playerTwo_id');
}
}
控制器方法:
public function index()
{
$matchs = Match::with('playerOne', 'playerTwo')->orderBy('created_at', 'asc')->get();
return $matchs;
//return new MatchsCollection($matchs);
}
和我的数据库如下所示: (匹配表)
id | playerOne_id | playertwo_id | winner_id | status
------------------------------------------------------------
1 | 1 | 3 | 0 | PENDING
2 | 2 | 1 | 0 | PENDING
3 | 3 | 2 | 0 | PENDING
和用户表:
id | name | email
-----------------------------------
1 | John | John@email.com
2 | Mark | Mark@email.com
3 | Harry | Harry@email.com
当我调用我的api时,我得到以下结果:
[
{
id: 1,
playerOne_id: 1,
playerTwo_id: 3,
winner_id: 0,
status: "PENDING",
created_at: "2019-01-10 00:00:00",
updated_at: null,
users: [
{
id: 1,
name: "John",
email: "John@email.com",
email_verified_at: null,
created_at: "2019-01-11 10:38:26",
updated_at: "2019-01-11 10:38:26"
}
]
},
{
id: 2,
playerOne_id: 2,
playerTwo_id: 1,
winner_id: 0,
status: "PENDING",
created_at: "2019-01-11 08:26:28",
updated_at: "2019-01-11 08:26:28",
users: [
{
id: 2,
name: "Mark",
email: "Mark@email.com",
email_verified_at: null,
created_at: "2019-01-11 10:40:13",
updated_at: "2019-01-11 10:40:13"
}
]
},
{
id: 3,
playerOne_id: 3,
playerTwo_id: 2,
winner_id: 0,
status: "PENDING",
created_at: "2019-01-11 08:45:22",
updated_at: "2019-01-11 08:45:22",
users: [
{
id: 3,
name: "harry",
email: "harry@email.com",
email_verified_at: null,
created_at: "2019-01-11 10:40:13",
updated_at: "2019-01-11 10:40:13"
}
]
}
]
我不想得到的是这个结果(我只是告诉你第一场比赛)
[
{
id: 1,
playerOne_id: 1,
playerTwo_id: 3,
winner_id: 0,
status: "PENDING",
created_at: "2019-01-10 00:00:00",
updated_at: null,
users: [
{
id: 1,
name: "John",
email: "John@email.com",
email_verified_at: null,
created_at: "2019-01-11 10:38:26",
updated_at: "2019-01-11 10:38:26"
},
{
id: 3,
name: "Harry",
email: "Harry@email.com",
email_verified_at: null,
created_at: "2019-01-11 10:38:26",
updated_at: "2019-01-11 10:38:26"
}
]
}
]
在Laravel中这可能吗?谢谢:)
答案 0 :(得分:0)
为了能够将所有玩家作为user
数组的一部分返回,您可以将Match
和User
之间的关系更改为belongsToMany (many-to-many)或简单地进行操作从控制器返回匹配数据之前。
将其更改为BelongsToMany
是我的建议,因为从语义上讲它更有意义,但是,我知道(取决于您到目前为止已完成的工作量)它可能不切实际。
您需要:
matchs
表重命名为matches
(这也意味着您可以删除protected $table = 'matchs';
模型类中的Match
。创建一个名为match_user
的表。如果您的项目正在使用迁移,则可以运行:
php artisan make:migration create_match_user_table --create=match_user
在该迁移中,您需要将up()
方法的内容更改为:
public function up()
{
Schema::create('match_user', function (Blueprint $table) {
$table->integer('match_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
$table->primary(['match_id', 'user_id']);
});
}
运行php artisan migrate
在您的Match
模型中,将users()
关系更改为:
public function users()
{
return $this->belongsToMany(User::class)->withTimestamps();
}
如果表中的数据是虚拟数据,则可以跳过此步骤。否则,您需要将playerOne_id
和playertwo_id
信息移到新的数据透视表中。您可以执行以下操作:
Match::all()->each(function ($match) {
$match->users()->attach([$match->playerOne_id, $match->playertwo_id]);
});
在何处运行它并不重要,因为它只需运行一次,因此在运行它之后可以将其删除。我通常会在路线或修补程序中运行它。
然后进行清理。同样,如果您拥有的数据只是虚拟数据,那么我只需要删除原始迁移的playerOne_id
和playertwo_id
,否则创建一个删除那些字段Dropping columns docs
完成上述操作后,您只需在控制器中执行以下操作即可获得结果:
$matches = Match::with('users')->latest()->get();