关系设计

Relationship Design

我正在构建一个应用程序,客户可以在其中从预定义模板创建文档,使用自己的文本编辑一些字段并保存。我已经勾勒出我认为的关系,转换成 Laravel:

基本上没问题

我唯一的问题是如何处理 FieldValue 关系。这个想法是模板定义了所有字段,而不是在每个文档上重新创建这些字段,它应该只查看其模板。这意味着 FieldValue 需要查找其文档、模板并从那里找到相应的字段。

是否有一种简洁的方法来实现它,或者是否有更好的方法来设计关系以使其更易于实现?

希望这就是你的意思:

$doc = Document::findOrFail(Input::get('docId'));
$sections = $doc->template->sections;
$fieldValues = $doc->field values;

现在您只需 运行 字段值并获取字段和部分并开始放置内容。

为了获得更好的性能,我希望加载 fieldValue 参数:

->with('field');

根据您的图表,看起来像一个带有数据透视表的数据透视图 table...

在Laravel中通常会像这样建模:

class Document extends Model
{
    public function template()
    {
        return $this->belongsTo('App\Template');
    }

    public function fields()
    {
        return $this->belongsToMany('App\Field')->withPivot('value');
    }
}

class Template extends Model
{
    public function organisation()
    {
        return $this->belongsTo('App\Organisation');
    }

    public function documents()
    {
        return $this->hasMany('App\Document');
    }

    public function fields()
    {
        return $this->hasManyThrough('App\Field', 'App\Section');
    }

    public function sections()
    {
        return $this->hasMany('App\Section');
    }
}

class Section extends Model
{
    public function fields()
    {
        return $this->hasMany('App\Document')->withPivot('value');
    }

    public function template()
    {
        return $this->belongsTo('App\Template');
    }
}

class Field extends Model
{
    public function documents()
    {
        return $this->belongsToMany('App\Document')->withPivot('value');
    }

    public function section()
    {
        return $this->belongsTo('App\Section');
    }
}

class Organisation extends Model
{
    public function documents()
    {
        return $this->hasManyThrough('App\Document', 'App\Template');
    }

    public function templates()
    {
        return $this->hasMany('App\Template');
    }
}

与相关的 tables(如果坚持使用 laravel 默认值):

fields
    id - integer
    section_id - integer

documents
    id - integer
    template_id - integer

templates
    id - integer
    organisation_id - integer

sections
    id - integer
    template_id - integer

organisations
    id - integer

document_field
    id - integer
    document_id - integer
    field_id - integer
    value - string

然后您可以通过多种不同的方式访问内容。这是一个例子:

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

$organisation = $user->organisation;

foreach ($organisation->documents as $document)
{
    foreach ($document->fields as $field)
    {
        echo $field->pivot->value;
    }
}

并插入:

$field = App\Field::find(2);

$document = App\Document::find(4);

$value = 'My field value';

$document->fields()->save($field, ['value' => $value]);

相关文档:

回答你的第一个问题:

我建议您将其命名为内容。您可以像现在一样处理内容。目前的关系已经足够好了。您必须与其他 table 分开执行此操作。

第二个问题:更好的方法

我根据你的 ERD 自己创建了一个 ERD:

我改变了一些想法。

  1. 不是很重要,但文档来自用户。
  2. 模板可以有子模板。这样做的结果是您可以重用子模板。例如。如果您有徽标,则每次都可以将其放入您的文档中。
  3. 由于有了新模板 table,您不再需要版块。使用新方法,您可以定义 sub sections/templates.
  4. 属性都放在一个table。使用这种方法,您可以为字段定义无限属性。这可以分配得更灵活。这些被引用到字段和内容。 content_id 但是不需要。我只是把它放在那里,这样你就可以轻松地检查它适用于哪个字段。
  5. 你问题的重点是FieldValue/Content。内容参考文档。您可以从文档中填写模板的字段。

希望您清楚这一点。我看到的优点是:

  1. 属性更灵活
  2. 内容查找很容易并引用到一个字段

我没有对内容进行任何更改table。保持原样。这样就好了!希望这对你有帮助。如果您使用 Schema designer,您可以很容易地检索您的模型!