1

对不起什么是通用标题。我不是最擅长头衔的。

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

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

当然,这违反了 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() 从视图中调用该动作。但我听说这非常低效

现在,我在寻找解决问题的方法时发现了这两个想法,但根据他们的说法,这两个想法很糟糕,所以我想出了另外两个解决方案:

想法3:

将分页数据返回到视图时,我可以确保所有项目都有一个“user_id”键,以便我可以根据登录用户的 ID 检查视图中的键,以查看他/她是否拥有项目。但这需要 a)我重新编写分页 b)非常丑陋的查询,尤其是对于某些视图(搜索),c)整体丑陋和缓慢。所以我决定放弃这个想法

想法4:

每次视图需要知道一个项目是否归用户所有时,我都会从控制器传递另一个数组,其中包含用户拥有的所有项目,在视图中你可以使用 in_array() 检查用户是否拥有说项目。当然,这个问题很明显:如果用户有很多物品怎么办?

简而言之,我被困在这个问题上,我不知道从哪里开始,我将不胜感激!谢谢!

4

2 回答 2

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 设置为您喜欢的格式,并为视图设置该格式和 $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
}
于 2009-05-11T06:31:20.140 回答
0

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

于 2009-11-13T21:33:33.737 回答