繁体   English   中英

在 Laravel 中关联同一个 model 的多个单实例

[英]Associating multiple single instances of the same model in Laravel

我正在做一个项目,其中有一些事件,每个事件都与两个单独的 forms 相关,它们有两个独立的关系——预订和调查。 这些 forms 构造相同,因此似乎没有必要使用两个完全不同的形式模型——我想使用多态关系,但似乎不可能。

构建这种关系的适当方式是什么?

  • 活动有一个或没有预订表格
  • 活动有一个或没有调查表
  • Forms 是单独的单表

我试过的:

  • 多态关系:与同一个 model 的两个关系不兼容。
  • 有一个关系:这使用了booking_idsurvey_id ,但拒绝设置这些字段中的任何一个。
  • 与类型字段有很多关系:很难轻松保存 forms,因为无法保存到单个关系。 forms 的数量也没有限制。
class Event extends Model
{
    public function booking()
    {
        return $this->hasOne(Form::class, 'id', 'booking_form_id');
    }

    public function survey()
    {
        return $this->hasOne(Form::class, 'id', 'survey_form_id');
    }
}

...

class Form extends Model
{
    public function event()
    {
        return $this->belongsTo(Event::class);
    }
}

...

$event = new Event;
$event->name = 'Event';
$event->save();

$booking = new Form;
$booking->name = 'booking';
$event->booking()->save($booking);

$survey = new Form;
$survey->name = 'survey';
$event->survey()->save($survey);

...

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

    $table->string('name');

    $table->unsignedInteger('booking_form_id')->nullable()->index();
    $table->unsignedInteger('survey_form_id')->nullable()->index();

    $table->timestamps();
});

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

    $table->string('name');

    $table->timestamps();
});

什么会更好:

  • 使用允许 forms 用于应用程序的其他部分的多态关系。
  • 使用多个 hasOne 关系将 forms 的数量限制为每种类型一个。

我认为您的参数顺序错误。 它是hasOne($related, $foreignKey, $localKey)

class Event extends Model
{
    /* if you haven't changed the default primary keys, $localKey should be equal to 'id' */ 
    public function booking()
    {
        return $this->belongsTo(Form::class, 'booking_form_id');
    }

    public function survey()
    {
        return $this->belongsTo(Form::class, 'survey_form_id');
    }
}
class Form extends Model
{
    public function booking_event()
    {
        return $this->hasOne(Event::class, 'booking_form_id');
    }

    public function survey_event()
    {
        return $this->hasOne(Event::class, 'survey_form_id');
    }
}

现在有两种方法可以解决这个问题。

  1. 如果一个 Form 可以同时属于这两种事件,你需要在访问$form->event时返回一个集合。
  2. 如果一个 Form 只能属于一种事件,则需要在访问$form->event时猜测是哪一种并返回 model 。
# Form model
# 1. can be achieved using an accessor. Cannot be eager loaded but can be appended with the $appends Model property
public function getEventsAttribute()
{
    return collect([$this->booking_event, $this->survey_event]);
}
# Form model
# 2. can be achieved using a relationship that guesses which relation it should return. Since it returns a relationship, it can be eager loaded.
public function event()
{
    return ($this->booking_event()->count() != 0) ? $this->booking_event() : $this->survey_event();
}

暂无
暂无

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

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