I am really stuck using a custom model for my pivot, and don't understand why can we make a custom model for it if we can't use it as a model. I've seen many answers and articles, and all chose to extend Pivot or Model, but real life usage is never taken into account and never go any further than giving it a "named" class.
我真的不习惯使用我的支点的自定义模型,并且不明白为什么我们可以为它制作自定义模型,如果我们不能将它用作模型。我已经看过很多答案和文章,所有人都选择扩展Pivot或Model,但是现实生活中的使用从未被考虑过,而且从来没有比给它一个“命名”类更进一步。
Here is an example of what I'm trying to achieve: My main models: Player model, with players table. Game model, with games table.
这是我想要实现的一个例子:我的主要模型:玩家模型,玩家表。游戏模型,带游戏桌。
Player and Game have a many-to-many relationship, that we can call "Party" with a "game_player" table.
玩家和游戏有多对多的关系,我们可以用“game_player”表称为“Party”。
Less important for now, I have also a Score model that holds the score/turns, a Party can have many scores, so scores table has a party_id entry.
现在不太重要的是,我还有一个持有得分/转弯的分数模型,一个Party可以有很多分数,因此分数表有一个party_id条目。
So, here are basically my classes (Laravel 5.2):
所以,这里基本上是我的课程(Laravel 5.2):
Player
class Player extends Model
{
// The Games this Player is participating to.
public function games() {
return $this->belongsToMany(Game::class)->withPivot('id')->withTimestamps();
}
// The Scores belonging to this Player.
public function parties() {
return $this->hasManyThrough(Score::class, Party::class);
}
// The Custom Pivot (Party) creation for this Player.
public function newPivot(Model $parent, array $attributes, $table, $exists) {
if ($parent instanceof Game) {
return new Party($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
}
Game
class Game extends Model
{
// The Players participating into this Game.
public function players() {
return $this->belongsToMany(Player::class)->withPivot('id')->withTimestamps();
}
// The Scores belonging to this Party.
public function parties() {
return $this->hasManyThrough(Score::class, Party::class);
}
// The Custom Pivot (Party) creation for this Game.
public function newPivot(Model $parent, array $attributes, $table, $exists) {
if ($parent instanceof Player) {
return new Party($parent, $attributes, $table, $exists);
}
return parent::newPivot($parent, $attributes, $table, $exists);
}
}
Party
class Party extends Pivot
{
protected $table = 'game_player';
// The Player this Party belongs to.
public function player() {
return $this->belongsTo(Player::class);
}
// The Game this Party belongs to.
public function event() {
return $this->belongsTo(Game::class);
}
// The Scores belonging to this Party.
public function scores()
{
return $this->hasMany(Score::class);
}
}
Score
class Score extends Model
{
// The Party this Score belongs to (has "party_id" column).
public function party() {
return $this->belongsTo(Party::class);
}
}
Now, I have two different sets of problems that appear depending on if I extend Model or Pivot on Party:
现在,我有两组不同的问题出现,具体取决于我是否扩展了Party上的Model或Pivot:
1) When Party extends Pivot:
1)当Party扩展Pivot时:
- Can't do something like Party::count(), anything that works with models.
- Can't do something like Party::where("player_id", $player->id) and so on ... Basically I want the party to have a scores/turns table attached to it and to do so I need to select the pivot model.
- Can't do something like $events->player->first()->scores() nor event $events->player->first()->pivot->scores(), it breaks with the following:
不能做像Party :: count(),任何与模型一起使用的东西。
不能做像Party :: where(“player_id”,$ player-> id)等等...基本上我希望派对上有一个得分/转牌表,这样做我需要选择枢轴模型。
无法执行类似$ events-> player-> first() - > scores()或事件$ events-> player-> first() - > pivot-> scores(),它会突破以下内容:
PHP error: Argument 1 passed to Illuminate\Database\Eloquent\Relations\Pivot::__construct() must be an instance of Illuminate\Database\Eloquent\Model
PHP错误:传递给Illuminate \ Database \ Eloquent \ Relations \ Pivot :: __ construct()的参数1必须是Illuminate \ Database \ Eloquent \ Model的一个实例
2) When Party extends Model:
2)当Party扩展模型时:
- Can do trivial things such as Party::count(), Party::where("Game_id", $game->id)
- Lose all pivot functions, so can't do $game->players, not even $game->players() work: $game->players()->count() is correct, but $game->players()->first() or $game->players->first() will break with the following:
可以做一些琐碎的事情,比如Party :: count(),Party :: where(“Game_id”,$ game-> id)
失去所有的枢轴功能,所以不能做$ game->玩家,甚至不是$ game-> players()工作:$ game-> players() - > count()是正确的,但$ game-> players() - > first()或$ game-> players-> first()将破坏以下内容:
PHP error: Argument 1 passed to Illuminate\Database\Eloquent\Model::__construct() must be of the type array, object given
PHP错误:参数1传递给Illuminate \ Database \ Eloquent \ Model :: __ construct()必须是类型数组,给定对象
Question:
How to correctly use the custom pivot model when instantiating them is different?
在实例化它们时如何正确使用自定义枢轴模型是不同的?
I hope to achieve the following:
我希望实现以下目标:
- Do the normal $events->players->attach($player)
- Be able to attach a score like $score->party_id = $events->players->find($x)->pivot->id (or any other way via a scope for example)
- Be able to count all parties being played, or the ones on one specific game or by a specific player (something like Party::count(), $player->parties->count() etc)
做正常的$ events-> players-> attach($ player)
能够附加分数,如$ score-> party_id = $ events-> players-> find($ x) - > pivot-> id(或通过范围的任何其他方式)
能够计算正在玩的所有方,或特定游戏或特定玩家的方(如Party :: count(),$ player-> parties-> count()等)
Thank you.
1 个解决方案
#1
0
For my -little- experience with laravel i've found that pivot tables
are used when you have a many-to-many
relatinship that only keeps one link between a specific object from the table A to the table B. For example User with Role.
对于我对laravel的一点体验,我发现当你有多对多的关系时只使用表A中的特定对象与表B之间保持一个链接,就会使用数据透视表。例如,带角色的用户。
As you can image, a user A just need one link/relation with the role B. But what happens if we want to use a pivot table (for example Sales) that needs to keep different records between userA and productB? I haven't found a direct way to do this.
由于您可以成像,因此用户A只需要与角色B建立一个链接/关系。但是,如果我们想要使用需要在userA和productB之间保留不同记录的数据透视表(例如Sales),会发生什么?我没有找到直接的方法来做到这一点。
My solution is treat the intermadiate table as an actual model, then make one-to-many relationships with both tables (users-sales and products-sales) and then if, I need to, relate this middle model with another ones.
我的解决方案是将intermadiate表视为实际模型,然后与两个表(用户 - 销售和产品 - 销售)建立一对多关系,然后如果我需要将此中间模型与另一个模型相关联。
So in your case, i'd have 4 clear models:
所以在你的情况下,我有4个明确的模型:
-
Player |
one-to-many
with Party -
Game |
one-to-many
with Party -
Party |
one-to-one
with Score |many-to-one
with Party |many-to-one
with Player -
Score |
one-to-one
with Party
播放器|与党一对多
游戏|与党一对多
派对|与分数一对一|与党多对一|与玩家多对一
得分|与党一对一
With this approach you also has more control of the properties of each model.
使用这种方法,您还可以更好地控制每个模型的属性。
#1
0
For my -little- experience with laravel i've found that pivot tables
are used when you have a many-to-many
relatinship that only keeps one link between a specific object from the table A to the table B. For example User with Role.
对于我对laravel的一点体验,我发现当你有多对多的关系时只使用表A中的特定对象与表B之间保持一个链接,就会使用数据透视表。例如,带角色的用户。
As you can image, a user A just need one link/relation with the role B. But what happens if we want to use a pivot table (for example Sales) that needs to keep different records between userA and productB? I haven't found a direct way to do this.
由于您可以成像,因此用户A只需要与角色B建立一个链接/关系。但是,如果我们想要使用需要在userA和productB之间保留不同记录的数据透视表(例如Sales),会发生什么?我没有找到直接的方法来做到这一点。
My solution is treat the intermadiate table as an actual model, then make one-to-many relationships with both tables (users-sales and products-sales) and then if, I need to, relate this middle model with another ones.
我的解决方案是将intermadiate表视为实际模型,然后与两个表(用户 - 销售和产品 - 销售)建立一对多关系,然后如果我需要将此中间模型与另一个模型相关联。
So in your case, i'd have 4 clear models:
所以在你的情况下,我有4个明确的模型:
-
Player |
one-to-many
with Party -
Game |
one-to-many
with Party -
Party |
one-to-one
with Score |many-to-one
with Party |many-to-one
with Player -
Score |
one-to-one
with Party
播放器|与党一对多
游戏|与党一对多
派对|与分数一对一|与党多对一|与玩家多对一
得分|与党一对一
With this approach you also has more control of the properties of each model.
使用这种方法,您还可以更好地控制每个模型的属性。