Laravel多态关系多种类型

时间:2020-06-26 23:03:19

标签: laravel eloquent eloquent-relationship

在以下情况下,我正在努力为关系建模。

模型类型-节点-连接-按钮

  • 一个Node具有0个输入(),它们可以来自NodeButton

  • Node使用Connection枢轴连接到其输入。

  • 一个Node有一个0到另一个Node的output()。再次通过Connection

  • 一个Node有0-n个Button。 //易于实现,忽略

  • Button属于Node。 //易于实现,忽略

  • Button通过NodeConnection的输出为0的一个。

理想的API

$node1->output()->save($node2); // link two nodes
$node1->inputs()->save($node2); // links two nodes
$button->output()->save($node1); // links a button and a node
$node1->inputs()->save($button); // links a node and a button

// replace save() with attach() or associate(), I forget which it is!

Connection::all()应该给我与他们的所有联系

  • source_id,可以是Node标识,也可以是Button标识。
  • source_type,可以是nodebutton
  • destination_id,它是一个Node ID。

为便于可视化而大致假定的模型属性类型。

  • $button->node = Node
  • $button->output = Node|null
  • $button->output->pivot = Connection
  • $node->output = Node|null
  • $node->output->pivot = Connection
  • $node->inputs = Collection<Node|Button>|null
  • $connection->destination = Node
  • $connection->source = Node|Button

enter image description here

我认为我的主要问题是多态关系要求您设置要变形的模型的类型,而不是从传入的模型中获取它,因此,我正在努力研究{ {1}} Node方法可以像inputs()一样工作,需要我指定一个模型,该模型需要传递morphToMany()Node

-

我发现了这些堆栈溢出问题,但似乎无法将它们映射到我的用例。

1 个答案:

答案 0 :(得分:0)

再考虑一下之后,我不确定为什么我们在这里使用多态。

如果您确实有更深层次的理由想要多态,那么下面的解决方案将不起作用。

迁移:

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

Schema::create('buttons', function (Blueprint $table) {             
    $table->bigIncrements('id');
    $table->unsignedBigInteger('node_id')->nullable();
    $table->string('name');
    $table->timestamps();
});

Schema::create('connections', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->unsignedBigInteger('input_id');
    $table->unsignedBigInteger('output_id');
    $table->timestamps();
    $table->foreign('input_id')->references('id')->on('nodes');
    $table->foreign('output_id')->references('id')->on('nodes');
});

连接模型

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;

class Connection extends Pivot
{
    protected $table = 'connections';
    
    public function input()
    {
        return $this->belongsTo(Node::class, 'input_id');
    }

    public function output()
    {
        return $this->belongsTo(Node::class, 'output_id');
    }
}

节点模型:

<?php
namespace App\Models;

class Node extends Model
{
    public function inputs()
    {
        return $this->hasManyThrough(
            Node::class,
            Connection::class,
            'output_id',
            'id',
            'id',
            'input_id'
        );
    }

    public function output()
    {
        return $this->hasOneThrough(
            Node::class,
            Connection::class,
            'input_id',
            'id',
            'id',
            'output_id'
        );
    }

    public function connection()
    {
        return $this->hasOne(Connection::class, 'output_id');
    }

    public function buttons()
    {
        return $this->hasMany(Button::class);
    }
}

按钮模型

<?php
namespace App\Models;

class Button extends Model
{
    public function node()
    {
        return $this->belongsTo(Node::class);
    }
}

现在,如果不为按钮添加一些额外/更高级的关系,您将无法完全顺畅地完成所有操作。

$button->node = Node (Works)
$button->output = Node|null ($button->node->output)
$button->output->pivot = Connection ($button->connection)
$node->output = Node|null (Works)
$node->output->pivot = Connection ($node->connection)
$node->inputs = Collection<Node|Button>|null (Works)
$connection->destination = Node ($connection->output)
$connection->source = Node|Button ($connection->input)

希望有帮助。如果您确实需要多态关系,我以后可以再考虑。

***编辑****

重新阅读您的问题后,我的回答是根据以下陈述制定的:

按钮属于节点。 //易于实现,忽略

哪个使$ connection-> source = Node | Button在我的解决方案中不正确

您将需要$ connection-> input-> buttons()-> ...

相关问题