Model view controller 从一个模型加载数据,并将其构造为来自另一个模型的数据

Model view controller 从一个模型加载数据,并将其构造为来自另一个模型的数据,model-view-controller,cakephp,cakephp-1.3,Model View Controller,Cakephp,Cakephp 1.3,我在我们的网站上有静态和动态产品。静态产品是从数据库加载的基本产品。动态产品是用户动态生成的(来自“设计您自己的戒指”等应用程序) 进行购买时,对于售出的每个产品,都有一个名为“购买”的表/模型条目,购买模型保存售出产品的销售价格、数量等。购买模式有一个产品 这适用于静态产品。然而,动态产品需要将其数据保存在某个地方。我不想将动态产品保存到products表中,因为我不希望它们显示在除购买之外的任何其他地方。此外,它们还可以包含静态产品没有的额外值 但是,当我加载动态产品数据时,我希望它像常规产

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

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

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

但是,当我加载动态产品数据时,我希望它像常规产品一样结构化,这样我就不必编写不同的逻辑来处理静态和动态产品

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

id      purchase_id     model       attribute       value

1       3               Product     name            foo
2       3               Product     description     bar
3       3               Other       size            7
我会将购买设置为拥有许多小牛。但加载此数据的默认方式如下所示:

[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
                        )
                )
        )
我想这样构造它:

[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回调中所做的更改


那我怎么才能做到呢?此外,如果有人能一起为我的问题提供更好的解决方案,那也很受欢迎

您两次使用$results


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

我重写了您的函数,以执行您实际想要的操作。看到它在这里工作了吗


由于到目前为止我没有接触过CakePHP,这在上下文中可能是微妙的错误。但是,函数本身似乎创建了您在问题中描述的内容。

这没有效果,我用新的
$results
覆盖了原始的
$results
。我尝试创建
$new\u results
并返回该结果(根据您的建议),但没有区别。您是否将
$primary
设置为true/false?我没有对
$primary
执行任何操作?如果是,在哪里?还要注意,如果我只是更改
$results
数组中的值,它就工作了。只有当我实际更改
$results
数组的结构时,它才会失败。我认为如果数组结构被破坏,可能会在内核的某个地方进行检查,忽略
afterFind
的结果。但我似乎找不到位置。我尝试将$primary设置为true,然后设置为false。两者都没有任何效果。我认为问题更多的是改变
$results
的数组结构,使其不再类似于Mav模型。谢谢,这在您的示例中确实有效。函数本身确实返回了我想要的结果。然而,我认为框架中的其他地方阻止了它的工作。这个函数不是我自己调用的,而是通过数据模型加载数据时运行的回调或钩子。它应该是这样,你可以改变返回的数据,事实上,当我只是改变数组值,而不是它工作的数组结构时。当我改变数组时,虽然它不工作。我不认为函数中有任何错误,但框架核心中的某些地方阻止了这一点。@John Isaacks:这确实很奇怪。我不知道为什么函数必须返回一个值,因为它可以通过引用在原始数组上完美地工作(在我阅读相关文档之前,我的答案的第一个版本就是这样做的)。您可以轻松地尝试声明
afterFind(&$results,$primary)
并注释掉
return
语句,看看这是否有什么不同。我尝试了一下,得到了这个错误:
致命错误:无法在第893行的cake/libs/model/datasources/dbo_source.php中通过引用传递参数1
我查看了第893行的代码及其:
$data=$model->{$className}->afterFind(数组($className=>$results[$i][$className])),false);
这是因为数组是匿名的吗?@John:是的,在PHP中不能像这样通过引用传递。必须先将数组存储在变量中。