如何在不破坏CakePHP中的MVC框架的情况下实现这一目标?

时间:2009-05-11 03:08:15

标签: php cakephp model views model-view-controller

抱歉什么是通用标题。我不是最好的头衔。

无论如何,Cake传递数据的方式(作为哈希)几乎是我甚至需要提出这个问题的原因。如果我将一个变量/ obj从控制器传递给视图,那么我可以向其提出问题(即$ duck-> quack()),而不是让它成为数组/字典(即$ duck [ '鸭'] ['嘎嘎'] ==真)这很容易。

我的应用程序中包含的是用户x可以拥有或不拥有的项目列表。在某些视图中,我显示数据库/应用程序中的所有项目(即分页)以及我需要知道的每个项目,如果登录用户是否拥有它。要回答这个问题,我需要进行查询(由于复杂的HABTM关系),这是在模型中完成的。换句话说,我的Item模型有一个函数isOwnedByUser($ user_id,$ item_id),如果它由用户拥有,则为true。我想从视图中调用此函数。

当然这违反了MVC框架,但我不确定如何做到这一点。我有四个想法:

创意1:

在帮助者中执行此操作:

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()来检查如果用户拥有该项目。当然,问题很明显:如果用户有很多项目怎么办?

总之我被困在这里,我不知道从哪里开始,我会感激所有的帮助!谢谢!

2 个答案:

答案 0 :(得分:3)

我将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,并为视图设置该项目和$项目。那会带你到你的选项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
}

答案 1 :(得分:0)

我知道这是一个老问题,但似乎ACL组件可能是一个不错的选择。