2015-04-13 10 views
4

Я создаю приложение, в котором клиенты могут создавать документ из заранее определенного шаблона, редактировать некоторые поля со своим собственным текстом и сохранять его. Я набросал отношения, как я думаю, что они будут, и это в основном нормально конвертировать в Laravel:Дизайн взаимоотношений

enter image description here

Единственный вопрос у меня есть, как я бы обрабатывать FieldValue отношения. Идея состоит в том, что Template определяет все поля, а затем вместо их повторного создания на каждом документе, он должен просто посмотреть на свой шаблон для них. Это означало бы, что FieldValue должен смотреть на свой Документ, на Шаблон этого и находить соответствующее поле оттуда.

Есть ли чистый способ реализовать это, или есть лучший способ разработки отношений, чтобы сделать его более практичным для реализации?

ответ

1

Двигаясь по диаграмме, выглядит сводной таблицы с данными шарнирных ...

Какой бы вообще быть смоделированы, как это в 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'); 
    } 
} 

с связанных таблиц (если придерживаться 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]); 

Соответствующие документы:

+0

Я даю этот ответ: примите + 100 щедростей; Я фактически использовал часть ответа Арьяна (объединение шаблонов и разделов и объединение форматирования в одну таблицу), но этот ответ был более полезен в основной проблеме, которую я имел – Joe

1

Надежда это то, что вы имели в виду:

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

Теперь вы просто запустите на значения полей и получить поле и раздел и начать размещение материала.

Для лучшей производительности я бы охотно нагрузки параметры fieldValue с:

->with('field'); 
+0

Вы предлагаете вручную перебирать как поля, так и значения полей в соответствии с ними на основе имени ключа (возможно, это сделано в коде экземпляра для документа)? Если так, я надеялся найти способ структурирования, чтобы это происходило более органично - если нет, не могли бы вы прояснить, пожалуйста? :-) – Joe

+0

Я имею в виду, что вы можете перебирать fieldValue и для каждого из них вы можете легко получить поле и раздел. –

1

Чтобы дать ответ вы первый вопрос:

я предлагаю, что вы называете его содержание. Вы можете обрабатывать контент, как сейчас. Отношения как есть достаточно хороши. Вы должны сделать это отдельно от других таблиц.

Второй вопрос: лучший способ

Я создал ERD сам на основе вы ERD:

Я изменил несколько думает.

  1. Не так важно, но документ принадлежит пользователю.
  2. Шаблоны могут иметь вспомогательные шаблоны. Следствием этого является то, что вы можете повторно использовать дополнительные шаблоны. Например. если у вас есть логотип, вы можете просто разместить это в своем документе каждый раз.
  3. Из-за новой таблицы шаблонов вам больше не нужны секции. С помощью нового подхода вы можете определить подразделы/шаблоны.
  4. Все объекты помещаются в один стол. При таком подходе вы можете определить бесконечные свойства для полей. Это может быть более гибким. Они относятся к полю и содержимому. Однако content_id не требуется. Я только что разместил его там, чтобы вы могли легко проверить, в каком поле оно применяется.
  5. Главное, что вы задавали вопрос FieldValue/Content. Содержимое ссылается на документ. Из документа вы можете заполнить поля шаблона.

Надеюсь, это ясно для вас. Преимущества я вижу, являются:

  1. Более гибкая в свойствах
  2. Содержимое поиска легко и ссылки на поле

Я не изменил ничего на столе контента. Просто оставьте это как есть. Так хорошо! Надеюсь, это вам поможет. Если вы используете Schema designer, вы можете легко получить ваши модели!

+0

Я принял и наградил 100 баунти фунги, так как его ответ был немного более ясный, но я намеревался начать еще одну награду за 50 репрессий, чтобы наградить вас ответом, поскольку несколько моментов, которые вы сделали, были очень полезными; в частности, указывая, что шаблоны и разделы могут быть объединены вместе, а также методы форматирования. К сожалению, я должен удвоить любую последующую награду, которую я присуждаю, поэтому я не создаю награду за 200 репрессий. У вас есть моя благодарность, хотя, если это хорошо :-) – Joe

+0

Я могу с этим справиться :) Я надеюсь, что мой совет был полезным. – ArjanSchouten

Смежные вопросы