【问题标题】:Deep linked values for a page in Laravel database modelsLaravel 数据库模型中页面的深度链接值
【发布时间】:2017-07-08 03:00:21
【问题描述】:

page 有多个元素,它们使用page_to_elements 表链接。每个element 有多个element_fields 并使用element_to_element_fields 链接。每个element_field 都有一个类型并使用element_to_element_fields 表链接。元素内每个element_field 的值都有一个值(在value_char、value_text 或value_num 中的eitehr),存储在element_values 表中。

数据库结构如下:

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',
                        'field_name_here' => 'Field value'
                    ),
                    [1] => array(
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value'
                    ),
                    [2] => array(
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value'
                    ),
                )
            )
        ),
        [1] => array(
            'element_name_here' => array(
                'fields' => array(
                    [0] => array(
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value'
                    ),
                    [1] => array(
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value'
                    ),
                    [2] => array(
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value',
                        'field_name_here' => 'Field value'
                    ),
                )
            )
        ),

    )
);

所以我需要类似下面的东西来生成上面的数组:

$page = Page::find($id);
print_r($page->getValues->toArray());

我有一些关于 belongsToMany 或 hasManyToMany 的经验,但从来没有这么深。

任何帮助将不胜感激。

【问题讨论】:

  • 您的模型中设置好所有关系了吗?
  • 是的。所以 element_fields 与元素等有关系。还设置了数据库关系。只需要从页面一直到值的深层链接
  • @davejal 这可以与多个中间模型一起使用吗?
  • 好吧,首先,您的 element_values 表结构错误。确定特定页面上的特定元素 page_to_element_id 就足够了,因此添加“页面”和“元素”字段是错误的。第二。是否所有 3 种类型的元素始终可用于每个页面?在这两种情况下 - 都必须进行更改。

标签: php mysql laravel laravel-5.1


【解决方案1】:

您的架构相当复杂,但我相信您可以通过预先加载关系和利用收集方法来实现您想要的结构。

<?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);
    }
}

【讨论】:

  • 谢谢,我明天试试这个
  • 我真的会推荐实施存储库模式
  • @VictorH.Avelar 你是什么意思?
  • @sebdesign 我试过了,它有点接近,但是字段都混乱了,没有获取正确的值。我会尝试找出逻辑,看看它是否有意义
  • @AlvinBakker 在您的示例中,我不确定字段数组键是什么,所以我假设它们对应于element_field_id。如果我能帮助你,请告诉我。
猜你喜欢
  • 1970-01-01
  • 2011-04-20
  • 2013-06-25
  • 1970-01-01
  • 2012-09-01
  • 2013-01-20
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多