首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >拉勒维尔,多到多的关系与多种模式

拉勒维尔,多到多的关系与多种模式
EN

Stack Overflow用户
提问于 2016-01-15 10:53:58
回答 2查看 6.5K关注 0票数 4

在Laravel 5中寻找一种简单的方法来完成以下操作。

想象一下这些模型和接口

  • 竞争
  • 用户
  • 团队
  • 参与者(用户和团队实现的接口)

比赛将与is参与者有多到多的关系,他们既可以是用户,也可以是团队。因此,我需要competition_participant枢轴表有以下列来定义模型

  • competition_id
  • participant_id
  • participant_type

但是我如何在竞争模型上写一个关系,以便它知道应该从数据库中获取哪个模型,同时返回一个混合模型的集合或接口类型的集合?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-15 16:29:01

对于哪些表应该得到哪些列,您有一些困惑。

参与者表需要是一个用于管理usersteams的多态关系的表。它至少接收一个particpatable_idparticpatable_type,以及一个idtimestamps()

然后,您需要一个名为competition_participant的额外表,它将管理属于competitions和多态表participants之间的多个表。

这将允许您将您的participants与您的competitions联系起来。这样,您就可以通过竞争来抓取所有参与者,调用它上的$participant->participatable属性,根据参与者的类型返回App\UserApp\Team

这都是经过测试的。

迁徙

代码语言:javascript
运行
复制
public function up()
{
    Schema::create('competitions', function(Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });

    Schema::create('teams', function(Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });

    Schema::create('participants', function(Blueprint $table) {
        $table->increments('id');
        $table->integer('participatable_id');
        $table->string('participatable_type');
        $table->timestamps();
    });

    Schema::create('competition_participant', function(Blueprint $table) {
        $table->integer('competition_id');
        $table->integer('participant_id');
    });
}

模型

代码语言:javascript
运行
复制
class Competition extends Model
{
    public function participants()
    {
        return $this->belongsToMany(Participant::class);
    }
}

class Participant extends Model
{
    public function participatable()
    {
        return $this->morphTo();
    }

    public function competitions()
    {
        return $this->belongsToMany(Competition::class);
    }
}

class Team extends Model
{
    public function participants()
    {
        return $this->morphMany(Participant::class, 'participatable');
    }
}

class User extends Authenticatable
{

    public function participants()
    {
        return $this->morphMany(Participant::class, 'participatable');
    }

}

种子

代码语言:javascript
运行
复制
public function run()
{
    $faker = Faker\Factory::create();

    // Seed Users Table
    DB::table('users')->delete();

    $users = [];
    for($i = 0; $i < 100; $i++) {
        $users[] = [
            'name' => $faker->name,
            'email' => $faker->email,
            'password' => Hash::make($faker->password),
            'created_at' => new DateTime,
            'updated_at' => new DateTime
        ];
    }
    DB::table('users')->insert($users);


    // Seed Teams Table
    DB::table('teams')->delete();
    $teams = [];
    for($i = 0; $i < 20; $i++) {
        $teams[] = [
            'name' => 'Team ' . ucwords($faker->domainWord),
            'created_at' => new DateTime,
            'updated_at' => new DateTime
        ];
    }
    DB::table('teams')->insert($teams);


    // Seed Participants Table
    DB::table('participants')->delete();

    // Insert some of our users as participants
    $users = App\User::limit(20)->orderByRaw('rand()')->get();
    foreach($users as $user) {
        $user->participants()->create([]);
    }

    // Insert some of the teams as participants
    $teams = App\Team::limit(10)->orderByRaw('rand()')->get();
    foreach($teams as $team) {
        $team->participants()->create([]);
    }

    // Seed Competitions Table
    DB::table('competitions')->delete();

    $competitions = [];

    for($i = 0; $i < 10; $i++) {
        $competitions[] = [
            'name' => $faker->company,
            'created_at' => new DateTime,
            'updated_at' => new DateTime,
        ];
    }

    DB::table('competitions')->insert($competitions);


    // Seed Competitions Participants Relationships
    DB::table('competition_participant')->delete();

    // Sign up each participant to 3 random competitions
    $participants = App\Participant::all();
    $competitions = App\Competition::all();

    foreach($participants as $participant) {
        $participant->competitions()->sync($competitions->shuffle()->take(3));
    }
}

用法

代码语言:javascript
运行
复制
    $competition = App\Competition::with('participants')->has('participants')->first();

    foreach($competition->participants as $participant) {
        echo get_class($participant->participatable); // Will output either App\User or App\Team
        echo "<br />";
    }
票数 11
EN

Stack Overflow用户

发布于 2016-01-15 14:47:59

这只是来自关于许多到多个多态关系的Laravel文档的复制粘贴。

为了帮助您更好地理解,这是您的模型与Laravel文档中的模型之间的映射:

代码语言:javascript
运行
复制
users == posts

teams == videos

competitions == tags

competitionables == tags

这就是您应该如何实现多态关系的方式,记住,每当您感到困惑时,只需查看文档以及模型与文档模型之间的映射:

表:

代码语言:javascript
运行
复制
users
    id - integer
    name - string

teams
    id - integer
    name - string

competitions
    id - integer
    name - string

competitionables
    competition_id - integer
    competitionable_id - integer
    competitionable_type - string

模型结构

代码语言:javascript
运行
复制
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get all of the Competition for the user.
     */
    public function competitions()
    {
        return $this->morphToMany('App\Competition', 'competitionable');
    }
}

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Team extends Model
{
    /**
     * Get all of the Competition for the Team.
     */
    public function competitions()
    {
        return $this->morphToMany('App\Competition', 'competitionable');
    }
}

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Competition extends Model
{
    /**
     * Get all of the users that are assigned to this Competition.
     */
    public function users()
    {
        return $this->morphedByMany('App\User', 'competitionable');
    }

    /**
     * Get all of the Teams that are assigned to this Competition.
     */
    public function teams()
    {
        return $this->morphedByMany('App\Video', 'competitionable');
    }
}

检索关系

代码语言:javascript
运行
复制
$user = App\User::find(1);

foreach ($user->competitions as $competition) {
    //
}

或者另一种方式

代码语言:javascript
运行
复制
$competition = App\Competition::find(1);

foreach ($competition->users as $user) {
    // do something with your users
}

foreach ($competition->teams as $team) {
    // do something with your teams
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34809469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档