关系设计
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:
我改变了一些想法。
- 不是很重要,但文档来自用户。
- 模板可以有子模板。这样做的结果是您可以重用子模板。例如。如果您有徽标,则每次都可以将其放入您的文档中。
- 由于有了新模板 table,您不再需要版块。使用新方法,您可以定义 sub sections/templates.
- 属性都放在一个table。使用这种方法,您可以为字段定义无限属性。这可以分配得更灵活。这些被引用到字段和内容。 content_id 但是不需要。我只是把它放在那里,这样你就可以轻松地检查它适用于哪个字段。
- 你问题的重点是FieldValue/Content。内容参考文档。您可以从文档中填写模板的字段。
希望您清楚这一点。我看到的优点是:
- 属性更灵活
- 内容查找很容易并引用到一个字段
我没有对内容进行任何更改table。保持原样。这样就好了!希望这对你有帮助。如果您使用 Schema designer,您可以很容易地检索您的模型!
我正在构建一个应用程序,客户可以在其中从预定义模板创建文档,使用自己的文本编辑一些字段并保存。我已经勾勒出我认为的关系,转换成 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:
我改变了一些想法。
- 不是很重要,但文档来自用户。
- 模板可以有子模板。这样做的结果是您可以重用子模板。例如。如果您有徽标,则每次都可以将其放入您的文档中。
- 由于有了新模板 table,您不再需要版块。使用新方法,您可以定义 sub sections/templates.
- 属性都放在一个table。使用这种方法,您可以为字段定义无限属性。这可以分配得更灵活。这些被引用到字段和内容。 content_id 但是不需要。我只是把它放在那里,这样你就可以轻松地检查它适用于哪个字段。
- 你问题的重点是FieldValue/Content。内容参考文档。您可以从文档中填写模板的字段。
希望您清楚这一点。我看到的优点是:
- 属性更灵活
- 内容查找很容易并引用到一个字段
我没有对内容进行任何更改table。保持原样。这样就好了!希望这对你有帮助。如果您使用 Schema designer,您可以很容易地检索您的模型!