页面包含多个元素,并使用page_to_elements表进行链接.每个元素都有多个element_fields,并使用element_to_element_fields进行链接.每个element_field都有一个类型,并使用element_to_element_fields表进行链接.元素中每个element_field的值具有存储在element_values表中的值(value_char,value_text或value_num中的eitehr).
以下是数据库结构的方式:
pages: id|name elements: id|name element_fields_types (sql_type can be char,text or num): id|name|sql_type element_fields (names can be title,intro,content,link,number,etc etc): id:element_field_type_id|name element_to_element_fields: id|element_id|element_field_id page_to_elements: id|page_id|element_id element_values: id|page_id|element_id|page_to_element_id|element_field_id|value_char|value_text|value_num
我正在寻找的是一个很好的hasManyToMany解决方案,可以在我请求页面ID时获取所有值.我现在有多个循环和数组创建来获得这样的结构(其中值来自正确的列名称,基于element_fields中设置的内容):
$page = array(
'elements' => array(
[0] => array(
'element_name_here' => array(
'fields' => array(
[0] => array(
'field_name_here' => 'Field value','field_name_here' => 'Field value','field_name_here' => 'Field value'
),[1] => array(
'field_name_here' => 'Field value',[2] => array(
'field_name_here' => 'Field value',)
)
),[1] => array(
'element_name_here' => array(
'fields' => array(
[0] => array(
'field_name_here' => 'Field value',)
);
所以我需要类似下面的东西来生成上面的数组:
$page = Page::find($id); print_r($page->getValues->toArray());
我对belongsToMany或hasManyToMany有一些经验,但从来没有这么深.
任何帮助将非常感激.
您的架构非常复杂,但我相信您可以通过急切加载关系和利用收集方法来实现您想要的结构.
<?PHP
class Page extends Eloquent
{
public function elements()
{
return $this->belongsToMany(Element::class,'page_to_elements');
}
public function values()
{
return $this->hasMany(Value::class);
}
public function getValues()
{
return $this->values()
// Eager-load the value element,the value field and its type
->with(['element','field.type'])->get()
// Group all the values by page element
->groupBy('page_to_element_id')->values()
// Group the values of each page element by the element name
->groupBy(function ($values) {
return $values->first()->element->name;
})
// Iterate each page element
->map(function ($values,$element) {
// Make an array with the element name as key and its fields as value
return [
$element => [
// Group the values by element field
'fields' => $values->groupBy('element_field_id')->values()
// Make an array with the field names and values for each element field
->map(function ($values) {
return $values->pluck('value','field.name')->all();
})->all(),],];
})->all();
}
}
class Element extends Eloquent
{
public function pages()
{
return $this->belongsToMany(Page::class,'page_to_elements');
}
public function fields()
{
return $this->belongsToMany(Field::class,'element_to_element_fields');
}
public function values()
{
return $this->hasMany(Value::class);
}
}
class Field extends Eloquent
{
public function type()
{
return $this->belongsTo(Type::class);
}
public function values()
{
return $this->hasMany(Value::class);
}
}
class Type extends Eloquent
{
public function fields()
{
return $this->hasMany(Field::class);
}
}
class Value extends Eloquent
{
public function page()
{
return $this->belongsTo(Page::class);
}
public function element()
{
return $this->belongsTo(Element::class);
}
public function field()
{
return $this->belongsTo(Field::class);
}
public function getValueAttribute()
{
$type = $this->field->type->sql_type;
return $this->getAttribute('value_'.$type);
}
}