为了账号安全,请及时绑定邮箱和手机立即绑定

Laravel (nova) 继承映射

Laravel (nova) 继承映射

PHP
慕哥9229398 2022-01-02 16:22:59
我目前正在构建一个 Laravel nova 应用程序。我希望能够通过继承映射实现类似于 Doctrine 可以做的事情。让我们假设以下示例:use Illuminate\Database\Eloquent\Model;class Event extends Model {    protected $attributes = [        'name' => null,        'starts_at' => null,        'ends_at' => null,    ];}class EventTypeA extends Event {  // has extra fields specific to EventTypeA}class EventTypeB extends Event {  // has extra fields specific to EventTypeB}现在我希望能够:获取所有EventTypeA的获取所有EventTypeB的获取所有事件并只关心共享信息。当然,对于上面的列表,所有 Eloquent 的优点,例如过滤、投影等都应该适用。据我所知laravel可能能够汉勒EventTypeA和EventTypeB正确但是Event不得不需要从两个表是不是真的有可能获取数据。我知道 eloquent 的变形功能,但是根据我的理解,这会导致Event核心数据和后代特定属性的单独 nova 视图。这在用户体验方面是不可接受的。我考虑过使用一个接口Event,EventTypeA然后EventTypeB将其实现。但是,我认为这将需要大量的体力劳动才能让 Eloquent 对事件做一些有意义的事情。这听起来像是一个常见问题,但是我无法找到有关如何在 laravel 中以正确方式执行此操作的任何资源(尤其是 nova 可以解决此问题)。
查看完整描述

2 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

Laravel 没有提供解决方案来为不同的表创建带有子类的基本模型。反过来也是完全可能的:


class Event extends Model

{

    protected $table = 'events';

}

class EventA extends Event

{

    protected static function boot()

    {

        parent::boot();


        static::addGlobalScope(function (Builder $query) {

            $query->where('events.type', '=', 'a');

        });

    }

}


class EventB extends Event

{

    protected static function boot()

    {

        parent::boot();


        static::addGlobalScope(function (Builder $query) {

            $query->where('events.type', '=', 'b');

        });

    }

}


我通过使用数据透视表的中间模型并将某些属性代理到子模型来解决类似的问题。


那么你的关系将是BelongsTo和HasMany。


在 UX 方面,您可以通过有条件地检查资源属性来自定义 Nova 中的字段。尽管我建议仅在详细信息和表单视图上执行此操作,因为在返回具有不同列的行时索引表将关闭。


public function fields(Request $request)

{

    return array_filter([

        ID::make()->sortable(),


        value(function () {

            if ($this->type === 'a') {

                return Boolean::make('A specific field')->hideFromIndex();

            }

        }),


        value(function () {

            if ($this->type === 'b') {

                return Boolean::make('B specific field')->hideFromIndex();

            }

        }),

    ]);

}


查看完整回答
反对 回复 2022-01-02
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

我最近才发现kirschbaum-development/nova-inline-relationship 这个包允许你将关系内联到一个 nova 资源中,因此允许一个像这样的结构:


class Event extends Model

{

  public function eventable()

  {

    return $this->morphTo();

  }

}

class Workshop extends Model

{

  public function event()

  {

    return $this->morphOne(Event::class, 'eventable');

  }

}

class StageTalk extends Model

{

  public function event()

  {

    return $this->morphOne(Event::class, 'eventable');

  }

}

然后在 nova 资源中


class Workshop extends Resource

{

  public function fields(Request $request)

  {

  return [

    MorphOne::make('Event')->inline(),

  ];

  }

}


查看完整回答
反对 回复 2022-01-02
  • 2 回答
  • 0 关注
  • 172 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信