从一个模型加载数据并将其结构化为来自另一个模型

时间:2011-06-01 15:07:18

标签: model-view-controller cakephp cakephp-1.3

我的网站上有静态和动态产品。静态产品是从数据库加载的基本产品。动态产品是用户即时生成的(来自“设计您自己的戒指”等应用程序。)

购买时,对于每个销售的产品,都有一个名为购买的表/模型的条目,购买模型保存销售价格销售产品的数量等。购买模式 hasOne 产品。

这适用于静态产品。但是,动态产品需要将数据保存在某处。我不想将动态产品保存到产品表中,因为我不希望它们出现在除购买之外的任何其他地方。此外,它们还可以包含静态产品所没有的额外值。

但是,当我加载动态产品数据时,我希望它的结构类似于常规产品,因此我不必编写不同的逻辑来处理静态产品和动态产品。

我提出了创建一个名为 mavs (模型属性值)的模型/表的想法,其表结构如下:

id      purchase_id     model       attribute       value

1       3               Product     name            foo
2       3               Product     description     bar
3       3               Other       size            7

我会将购买设为 hasMany mavs。加载此数据的默认方式如下所示:

[Purchase] => Array
        (
            [0] => Array
                (
                    ...
                    [Product] => Array
                        (
                        )
                    [Mav] => Array
                        (
                            [0] => Array
                                (
                                    [id] => 1
                                    [purchase_id] => 78
                                    [model] => Product
                                    [attribute] => name
                                    [value] => foo
                                )

                            [1] => Array
                                (
                                    [id] => 2
                                    [purchase_id] => 78
                                    [model] => Product
                                    [attribute] => description
                                    [value] => bar
                                )

                            [2] => Array
                                (
                                    [id] => 3
                                    [purchase_id] => 78
                                    [model] => Other
                                    [attribute] => size
                                    [value] => 7
                                )

                        )
                )
        )

我想像这样构建它:

[Purchase] => Array
        (
            [0] => Array
                (
                    ...
                    [Product] => Array
                        (
                            [name] => foo,
                            [description] => bar
                        )
                    [Other] => Array
                        (
                            [size] => 7
                        )
                )
        )

这样就可以像普通产品一样进行处理。


我认为我可以通过改变Mav模型中 afterFind 回调中的数据来实现这一目标。我创建了这个函数:

public function afterFind( $results, $primary )
{
    debug($results);

    foreach($results as $key => $data)
    {
        $model      = $data['Mav']['model'];
        $attribute  = $data['Mav']['attribute'];
        $value      = $data['Mav']['value'];

        $results[$key] = array( $model => array( $attribute => $value ) );
    }

    debug($results);

    return $results;
}

我在改变之前和之后对数据进行了调整:

Array
(
    [0] => Array
        (
            [Mav] => Array
                (
                    [id] => 1
                    [purchase_id] => 78
                    [model] => Product
                    [attribute] => name
                    [value] => foo
                )

        )

)

对此:

Array
(
    [0] => Array
        (
            [Product] => Array
                (
                    [name] => foo
                )

        )

)

这正是我的意图。但是,我从$purchase->find()获得的数据仍以原始方式构建。我不确定为什么它没有反映我在 afterFind 回调中所做的更改。

那我该如何实现呢?此外,如果任何人都可以一起提供更好的问题解决方案,那也是受欢迎的。

2 个答案:

答案 0 :(得分:1)

你两次使用$ results。

使用您喜欢的数据结构创建一个新数组并返回新数组。

答案 1 :(得分:0)

我重写了你的函数来做你实际上似乎想要的东西。看到它在这里工作:http://codepad.org/8ajWNai8

function afterFind( $results, $primary )
{
    foreach($results as &$currentResult)
    {
        foreach($currentResult["Mav"] as &$mavDetails)
        {
            $model     = $mavDetails['model'];
            $attribute = $mavDetails['attribute'];
            $value     = $mavDetails['value'];

            if (!array_key_exists($model, $currentResult)) 
            {
                $currentResult[$model] = array();
            }
            $currentResult[$model][$attribute] = $value;
        }
        unset($currentResult["Mav"]);
    }
    return $results;
}

由于到目前为止我已经对CakePHP进行了曝光,因此在上下文中这可能是错误的。然而,函数本身似乎正好创建了您在问题中描述的内容。