Загрузите данные из одной модели и структурируйте их так, как будто они пришли из другой - PullRequest
0 голосов
/ 01 июня 2011

У меня есть статические и динамические продукты на нашем сайте. Статические продукты - это ваши основные продукты, которые загружаются из базы данных. Динамические продукты генерируются пользователем на лету (из таких приложений, как " Создай свое собственное кольцо ").

Когда сделана покупка, для каждого проданного товара есть запись в таблице / модели под названием закупки , модель покупки содержит продажную цену , количество и т. Д. Для продукта, который был продан. Модель покупки имеет один товар.

Это прекрасно работает для статических продуктов. Однако динамические продукты должны где-то сохранять свои данные. Я не хочу сохранять динамический продукт в таблице продуктов, потому что я не хочу, чтобы он отображался где-либо еще, кроме покупок. Кроме того, они также могут содержать дополнительные значения, которых нет у статических продуктов.

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

Мне пришла в голову идея создания модели / таблицы с именем 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
                        )
                )
        )

Таким образом, он сможет обрабатываться так же, как обычный продукт.


Я думал, что смогу добиться этого, изменив данные в обратном вызове afterFind в модели Mav. Я создал эту функцию:

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 ]

1 голос
/ 01 июня 2011

вы используете $ results дважды.

создайте новый массив с понравившейся вам структурой данных и верните новый массив.

0 голосов
/ 03 июня 2011

Я переписал вашу функцию, чтобы сделать то, что вы на самом деле , казалось, намеревались.Посмотрите, как это работает здесь: 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, это может быть немного неправильно в контексте.Однако сама функция, кажется, создает именно то, что вы описываете в своем вопросе.

...