我试图寻找这个问题的答案,因为我确信它以前已经解决了,但是我找不到任何讨论cakephp如何格式化从模型返回的数据的东西。通常,我只是看到数据是如何来的,并根据每个Controller/View的需要处理它。然而,在这种情况下,我想重用我的视图,不幸的是,cakephp从不同的控制器向我传递数据的方式给我带来了问题。
我有2个模型,相关如下:
class Group extends AppModel {
public $hasMany = array( 'User' );
}
class User extends AppModel {
public $belongsTo = array(
'Group' );
}
我想让View/Groups/View/id
显示各个组的详细信息,以及属于该组的用户列表。理想情况下,我不想重新创建代码来显示用户列表,因为它已经存在于视图/Users/index
我发现我可以用$this-
在UsersController::index()中,我将调用$users=$this-
array(
(int) 0 => array(
'User' => array(
'id' => '100',
'group_id' => '101',
)
),
(int) 1 => array(
'User' => array(
'id' => '101',
'group_id' => '101',
)
)
)
在GroupsController中使用$this-
它返回一个组列表,但采用此格式,而不是debug($group['User'])代码>
'User' => array(
(int) 0 => array(
'id' => '101',
'group_id' => '101',
),
(int) 1 => array(
'id' => '100',
'group_id' => '101',
)
)
我是否可以改变调用模型数据的方式,使其以一致的方式在不同的控制器上传递,无论是主模型还是关联模型?或者我每次都必须循环浏览数据并以正确的格式重新构建数据?这似乎是一旦我的数据集增长,它将成为一个效率问题。
之所以以奇数格式获取数据,是因为您使用的是contain,这意味着无法获取相关数据(而不是直接数据)。
我建议您修改find()调用,而不是为此实现规范化:
$group = $this->GroupsController->Group->User->find('list', array(
'conditions' => array('User.group_id' => $id)
));
注意:在不需要时使用contain()会向SQL查询添加额外的连接,这将影响性能。
我不喜欢规范化/重新格式化我的CakePHP查找数据,因为它使它非标准。CakePHP总是以可预测的方式返回数据,这只是一个习惯它并使用适当的方法来检索数据的问题。
检索直接数据将以以下格式返回:
array(
(int) 0 => array(
'MODEL' => array(
'field1' => 'value1',
'field2' => 'value2',
)
),
(int) 1 => array(
'MODEL' => array(
'field1' => 'value1',
'field2' => 'value2',
)
)
)
检索直接数据和相关数据(使用Contain)将以以下格式返回:
array(
(int) 0 => array(
'MODEL' => array(
'field1' => 'value1',
'field2' => 'value2',
'RELATEDMODEL' => array(
(int) 0 => array(
'field1' => 'value1'
'field2' => 'value2'
),
(int) 1 => array(
'field1' => 'value1'
'field2' => 'value2'
)
)
)
),
(int) 1 => array(
'MODEL' => array(
'field1' => 'value1',
'field2' => 'value2',
'RELATEDMODEL' => array(
(int) 0 => array(
'field1' => 'value1'
'field2' => 'value2'
),
(int) 1 => array(
'field1' => 'value1'
'field2' => 'value2'
)
)
)
)
)
您的数据之所以不同,是因为您告诉MySQL获取相关数据,而不是直接获取。
如果您真的想规范化数据(我不建议这样做),请进一步阅读:
有几种方法可以做到这一点,但最合适的方法是在模型(或AppModel)的afterFind()回调中实现数据规范化。
>
1.3文件:http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Models.html#afterfind
2.x文件:http://book.cakephp.org/2.0/en/models/callback-methods.html#afterfind
这个回调是在找到适用的模型后执行的。在AppModel::afterfint()中实现它会影响应用中的每个查找调用。
旁注:规范化数据的一个简单方法是使用Set::extract(),然而,根据我的经验,由于实现的健壮性,它可能会比自己循环数据造成更多的开销。看看是否适合你的需要可能是个好主意。就我个人而言,我不会在afterFind()中使用它,因为它可能会添加一些过头的内容,但是,我将它包括在这里,因为它可能适合您的需要。
1.3设置提取留档:
2.0设置提取留档:
关于效率问题:执行常规循环不会增加太多开销。尽管如此,正常化当然会增加一点开销。
实际上,手动修改数组是不可取的。试图影响模型返回相关数据的方式也是不明智的。
我能想出的最好的办法如下。
假设您的用户索引具有以下内容:
foreach($users as $user) {
debug($user['User']); // made up for brevity
}
在foreach
块的开头添加以下内容:
if (!isset($user['User']) {
$user = array('User' => $user);
}
这似乎没那么贵。