Laravel, отношение «многие ко многим» к нескольким моделям

Ищете простой способ сделать следующее в Laravel 5.

Представьте себе эти модели и интерфейс

  • Соревнование
  • пользователь
  • команда
  • Участник (интерфейс, который реализует пользователь и команда)

Соревнование будет иметь отношение «многие ко многим» с участниками, которые могут быть как пользователями, так и командами. Поэтому мне нужно, чтобы в сводной таблице Competition_participant были следующие столбцы для определения моделей.

  • competition_id
  • participant_id
  • participant_type

Но как мне написать отношение к модели Соревнования, чтобы он знал, какую модель он должен извлечь из базы данных, и в то же время вернуть коллекцию смешанных моделей или типа Интерфейс?

4

Решение

У вас были некоторые сомнения относительно того, какие таблицы должны получать какие столбцы.

Ваша таблица участников должна быть таблицей для управления полиморфными отношениями users а также teams, Получает particpatable_id а также particpatable_type а также id а также timestamps() на самом минимуме.

Тогда вам нужна дополнительная таблица под названием competition_participant который будет управлять принадлежит многим между competitions и ваш полиморфный стол participants,

Это позволит вам связать ваши participants на ваш competitions, Таким образом, вы можете получить всех участников конкурса, позвоните $participant->participatable атрибут, который будет возвращать либо App\User или App\Team в зависимости от типа участника.

Это все проверено.

Миграции

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

модели

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

}

Семена

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

использование

    $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 />";
}
10

Другие решения

Это просто копия вставки из Документация Laravel о многих и многих полиморфных отношениях.

Чтобы помочь вам лучше понять, это соответствие между вашими моделями и моделями, указанными в документации Laravel:

users == posts

teams == videos

competitions == tags

competitionables == tags

Вот как вы должны реализовать свои полиморфные отношения, помните, когда вы чувствуете растерянность, просто посмотрите документацию и соответствие между вашими моделями и моделями документирования:

Таблицы:

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

Структура модели

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

Восстановление отношений

$user = App\User::find(1);

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

или другой способ

$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

По вопросам рекламы [email protected]