如何在不破坏 CakePHP 中的 MVC 框架的情况下做到这一点?
Posted
技术标签:
【中文标题】如何在不破坏 CakePHP 中的 MVC 框架的情况下做到这一点?【英文标题】:How can I do this without breaking the MVC framework in CakePHP? 【发布时间】:2009-05-11 03:08:14 【问题描述】:对不起,什么是通用标题。我不是最擅长头衔的人。
无论如何,Cake 传递数据的方式(作为哈希)几乎就是我什至需要问这个问题的原因。如果当我将一个变量/obj 从控制器传递到视图时,它是一个我可以向其提问的对象(即 $duck->quack() ),而不是让它成为一个数组/字典(即 $duck[' Duck']['quack'] == true) 这很容易。
我的应用中有一个用户 x 可以拥有或不拥有的项目列表。在某些视图中,我显示数据库/应用程序中的所有项目(即分页),并且对于每个项目,我需要知道登录用户是否拥有它。要回答这个问题,我需要做一个查询(由于复杂的 HABTM 关系),这是在模型内部完成的。换句话说,我的 Item 模型有一个函数 isOwnedByUser($user_id, $item_id) 如果它归用户所有,则该函数为真。我想从视图中调用这个函数。
这自然违反了 MVC 框架,但我不知道该怎么做。我有四个想法:
想法 1:
在 helper 中执行此操作:
App:Import('Model','Item');
$item = new Item();
$item->isOwnedByUser($user_id,$item_id);
并从视图中调用帮助程序(当然还传入 $item_id 和 $user_id)。但这确实违反了 MVC 框架。
想法 2:
在 item_controller.php 中创建一个动作并使用 requestAction() 从视图中调用该动作。但是我heard that this was extremeley inefficent
现在我在looking 时发现了这两个想法来解决我的问题,但根据他们的说法,这两个想法很糟糕,所以我想出了另外两个解决方案:
想法 3:
当将分页数据返回到视图时,我可以确保所有项目都有一个“user_id”键,以便我可以根据登录用户的 ID 检查视图中的键,以查看他/她是否拥有项目。但这需要a)我重新编写分页b)非常丑陋的查询,尤其是对于某些视图(搜索),c)整体丑陋和缓慢。所以我决定放弃这个想法
想法 4:
每次视图需要知道一个项目是否归用户所有时,我都会从控制器传递另一个数组,其中包含用户拥有的所有项目,在视图中你可以使用 in_array() 来检查如果用户拥有所述项目。当然这个问题很明显:如果用户有很多物品怎么办?
简而言之,我被困在这个问题上,我不知道从哪里开始,我会感谢所有帮助!谢谢!
【问题讨论】:
我还应该补充一点,Cake 处理 HABTM 关系的方式也很糟糕。真的很烂。但这与这个问题无关。 【参考方案1】:我会把 3 和 4 结合起来。
在你的行动中,在你获得所有分页项目之后:
$items = $this->paginate('Item');
获取他们的 ID 并将其与用户 ID 结合以获取所有用户的项目。
$itemIds = Set::extract('/Item/id', $items);
$usersItems = $this->Item->User->find
(
'all',
array
(
'conditions' => array
(
'User.id' = $userId,
'Item.id' => $itemIds
),
'fields' => array('User.id', 'Item.id')
)
);
现在您可以将 $usersItems 设置为您喜欢的格式,并为视图设置该格式和 $items。这将带你到你的选项 4 和 in_array(),除了它可能是 Set::extract() 或 Set::check()。
应该这样做:
if (Set::extract(sprintf('/Item[id=%s]', $itemId), $usersItems))
// user has the item
(我是凭记忆写的,所以……你知道如果失败了该怎么办:))
编辑:
或者,您可以执行以下操作(它应该比上述更快,只需确保将Set::extract()
移出循环):
$usersItemIds = Set::extract('/Item/id', $usersItems);
if (in_array($itemId, $usersItemIds))
// user has the item
【讨论】:
抱歉,我花了将近一天的时间才回复,但这很好用!我完全不知道 Set 实用程序,现在我可以重构一大堆低效编写的代码!再次感谢! 没问题!设置类是蛋糕中最好的东西之一,但不知何故不为公众所知。所以,广而告之! :)【参考方案2】:我知道这是一个老问题,但似乎 ACL 组件在这里可能是一个不错的选择。
【讨论】:
以上是关于如何在不破坏 CakePHP 中的 MVC 框架的情况下做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章