繁体   English   中英

Laravel ManyToMany关系-附加或分离事件

[英]Laravel ManyToMany Relationship - On Attach or Detach events

我解决这个问题的方法可能不是一个好主意。 我必须决定是使用多个数据透视表还是仅使用一个数据透视表,并过滤连接和分离事件。

我有一个关于艺术家的4个模特。 这些是; 艺术家,地点,活动,艺术品。 那里的模型可以帮助我确定艺术家去过哪些活动,地点以及他展出过哪些艺术品。 以及哪些艺术品出现在什么场所或事件上,以便我可以轻松地为每个模型调用Venues(),Arts(),Events(),Artists(),我应该得到该收藏。 我创建了一个数据透视表。 该表包含4列。

数据透视表

枢轴系统工作正常,除了您在图像中看到的那样,创建了多行,其中单行可能很明显。 艺术家可以参加在有艺术品的场地举行的活动。 因此,在这种情况下,您会期望一行没有任何0。 因此,上表将折叠为约3行。

艺术家模型:

class Artist extends Model {

...

public function Artworks (){
    return $this->hasMany('App\Artwork','author_id');
}

public function Events (){
    return $this->belongsToMany('App\Event', 'exhibits', 'artist', 'event');
}

public function Venues (){
    return $this->belongsToMany('App\Venue', 'exhibits', 'artist', 'venue');
}

...
}

作品模型:

class Artwork extends Model {
...
public function Events (){
    return $this->belongsToMany('App\Event', 'exhibits', 'artwork', 'event');
}

public function Venues (){
    return $this->belongsToMany('App\Artist', 'exhibits', 'artwork', 'venue');
}
...
}

事件模型:

class Event extends Model {
...
public function Venue (){
    return $this->belongsTo('App\Venue', 'venue_id');
}

public function Artists (){
    return $this->belongsToMany('App\Artist', 'exhibits', 'event', 'artist');
}

public function Artworks (){
    return $this->belongsToMany('App\Artwork', 'exhibits', 'event', 'artwork');
}
...
}

场地模型:

class Venue extends Model {
...
public function Events (){
    return $this->hasMany('App\Event', 'venue');
}

public function Artists (){
    return $this->belongsToMany('App\Artist', 'exhibits', 'venue', 'artist');
}

public function Artworks (){
    return $this->belongsToMany('App\Artworks', 'exhibits', 'venue', 'artworks');
}
...
}

只是为了澄清;

对于艺术品 :我应该能够了解艺术品的展览活动和地点。

对于艺术家 :我应该能够获得艺术家展示其作品的活动和地点

对于活动 :我应该能够了解该活动中的艺术品和艺术家。

对于场地 :我应该能够得到艺术家和艺术品的聚集地。

当可以使用单行时,数据透视表将创建多行。 艺术家可以参加一个活动场所来展示艺术品。

编辑:这关于优化表。 艺术品可能已经作为关系附加到表中的事件。 因此,现在假设我想将一个艺术家与同一个事件(艺术品关系)联系起来,如果我是手动进行的话,最好的方法是搜索某个事件中有艺术品但没有艺术家的地点,然后将艺术家与该事件联系起来-艺术品关系,而不是为艺术家与事件之间的关系以及艺术家与艺术品之间的关系创建新的2行,Laravel目前正在使用attach()

您应该使用许多数据透视表,但是在您的情况下,只需要有两个。

让我们逐步写下我们需要的内容,然后编写一些迁移:

  1. 在我们的系统中,我们想存储艺术家
  2. 每个艺术家可以有很多 艺术品
  3. 艺术品属于艺术家。
  4. 每个艺术家可以参观许多 活动
  5. 每场活动都有很多艺术品
  6. 在一个 地点举行活动
  7. 场地举行许多活动

粗体表示我们的实体,斜体表示我们之间的关系。

现在让我们设计数据库(表的架构非常基本):

1.创建艺术家表

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

2.创建艺术品表

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

    // An artwork belongs to an artist.
    // Because we know this, we also know that an artist has many artworks.
    $table->integer('artist_id');

    $table->timestamps();
});

3.创建事件表

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

    // An event is held at a venue.
    $table->integer('venue_id');

    $table->timestamps();
});

4.创建场地表

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

5.许多艺术家可以参观许多活动

Schema::create('artist_event', function(Blueprint $table)
{
    $table->integer('artist_id');
    $table->integer('event_id');
    $table->primary(['artist_id', 'event_id']);
});

6.在许多活动中展示许多艺术品

Schema::create('artwork_event', function(Blueprint $table)
{
    $table->integer('artwork_id');
    $table->integer('event_id');
    $table->primary(['artwork_id', 'event_id']);
});

(在此示例中,不处理外键,但是您应该对其进行设置以加快处理速度。)

现在,我们的迁移已完成,涵盖了列表中的每个要求。 如您所见,我们只需要两个数据透视表。

让我们看一下模型:

Artist.php

class Artist extends Model
{

    public function artworks()
    {
        return $this->hasMany(Artwork::class);
    }

    public function events()
    {
        return $this->belongsToMany(Event::class);
    }

}

Artwork.php

class Artwork extends Model
{

    public function artist()
    {
        return $this->belongsTo(Artist::class);
    }

    public function events()
    {
        return $this->belongsToMany(Event::class);
    }

}

Event.php

class Event extends Model
{

    public function artists()
    {
        return $this->belongsToMany(Artist::class);
    }

    public function artworks()
    {
        return $this->belongsToMany(Artwork::class);
    }

    public function venue()
    {
        return $this->belongsTo(Venue::class);
    }

}

Venue.php

class Venue extends Model
{

    public function events()
    {
        return $this->hasMany(Event::class);
    }

}

我们可以通过在数据库中插入一些虚拟数据并使用Psy Shell来处理模型来检查一切是否正常:

$ php artisan tinker
    Psy Shell v0.6.1 (PHP 7.0.0RC3 — cli) by Justin Hileman

>>> namespace App;


>>> $artist = Artist::find(1);
=> App\Artist {#680
     id: 1,
     name: "Peter Pan",
     created_at: "2015-12-09 01:06:01",
     updated_at: "2015-12-09 01:06:01",
   }


>>> $artworks = $artist->artworks;
=> Illuminate\Database\Eloquent\Collection {#677
     all: [
       App\Artwork {#681
         id: 1,
         name: "Fancy artwork",
         artist_id: 1,
         created_at: "2015-12-09 01:06:13",
         updated_at: "2015-12-09 01:06:13",
       },
     ],
   }


>>> $events = $artist->events;
=> Illuminate\Database\Eloquent\Collection {#684
     all: [
       App\Event {#686
         id: 1,
         name: "The greatest event ever",
         venue_id: 2,
         created_at: "2015-12-09 01:05:51",
         updated_at: "2015-12-09 01:05:51",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#685
           artist_id: 1,
           event_id: 1,
         },
       },
     ],
   }


>>> $event = Event::find(1);
=> App\Event {#692
     id: 1,
     name: "The greatest event ever",
     venue_id: 2,
     created_at: "2015-12-09 01:05:51",
     updated_at: "2015-12-09 01:05:51",
   }


>>> $venue = $event->venue;
=> App\Venue {#689
     id: 2,
     name: "Venue 2",
     city: "Miami",
     created_at: "2015-12-09 01:05:30",
     updated_at: "2015-12-09 01:05:30",
   }


>>> $artworksAtEvent = $event->artworks;
=> Illuminate\Database\Eloquent\Collection {#693
     all: [
       App\Artwork {#695
         id: 1,
         name: "Fancy artwork",
         artist_id: 1,
         created_at: "2015-12-09 01:06:13",
         updated_at: "2015-12-09 01:06:13",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#694
           event_id: 1,
           artwork_id: 1,
         },
       },
     ],
   }

泰勒·奥特威尔(Taylor Otwell)拒绝添加相关事件以更改belongsToMany关系,在此处查看更多信息https://github.com/laravel/framework/pull/14988,但此程序包解决了问题https://github.com/fico7489/laravel-pivot

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM