将两个相关模型中的字段组合到Display Field Cake PHP 2.0中

时间:2012-04-14 00:09:09

标签: cakephp-2.1

好吧,我彻底难倒了。我正在构建一个轻量级应用程序,以帮助我的朋友与他的业务。我不会涉及太多细节,但在某些背景下,他从几个品牌中获取组件并使用这些组件构建一个小部件。

由于每个小部件都有多个组件,并且其中一些不同的组件选项是由同一品牌制作的,因此我希望将品牌与组件分开,以便您可以轻松地按品牌查看产品。

我有以下表格

  • 品牌
  • 组件
  • 窗口小部件

品牌包含“id”和“name” 组件包含“id”“model”“brand_id” 小部件包含“id”“compoennt_id”

品牌的显示字段是“名称” 组件的显示区域是“模型”

这就是问题,在添加新产品时,蛋糕只会在表格中显示“模型”。我可以创建一个虚拟显示区域来显示以组合“brand_id”和“model”,但这并不能真正解决用户不知道该模型来自哪个品牌的问题。

看似懒惰的解决方案:一起删除品牌表并将该信息存储在组件表中。

有没有办法以不同的方式做到这一点,以便在添加新窗口小部件时,他们可以在下拉框中看到“品牌模型”?

2 个答案:

答案 0 :(得分:1)

昨天我花了太多时间研究同样的事情。

我认为你可以做的是在你的小部件模型中设置一个虚拟的显示区域,它可以像限制虚拟字段限制部分in this section of book.cakephp.com中那样建议:

    $this->virtualFields['cool_display_name'] = 
        sprintf('CONCAT(%s.name, " - ", %s.model)', $this->Brands->alias, $this-  >Components->alias);

但是:除非你的'find'函数在查询时获取足够的数据,否则这将无效。 find('list'),你可能正在调用你的下拉列表,默认递归设置为-1,所以它不会遍历得到它。我最终覆盖了我的Widget模型的find(),其中包括:

    public function find($type = 'first', $query = array()) {
    $return = array();
    switch ($type) {
        case 'list': // having to deal with a virtual field, seems like the least-messy workaround right now.
            $query['contain'] = 'User.full_name';
            $results = parent::find('all', $query);
            foreach($results as $k => $r) {
                $return[$r[$this->alias]['id']] = $r['User']['full_name'];
            }
            break;
        default:
            $return = parent::find($type, $query);
            break;
    }
    return $return;
}

我在那里做的是手工构建元素列表框所期望的数组,如:     array( 'id' => 'display text') 您还会在那里看到我使用了cakephp的Contain功能,因此不会返回所有数据,而只是我需要提供所有虚拟字段数据。< / p>

答案 1 :(得分:1)

我解决了类似的问题,但对我来说,有问题的模型没有有用的数据,我需要从其他两个相关模型中获取名称。我是CakePHP的新手,所以我不能保证这个解决方案有多“适当”,它的扩展程度等等......但它似乎有效。我也在CakePHP 1.3中使用它,所以我的解决方案可能甚至不适用于你。

无论如何,这是我添加到模型中的内容:

    function __construct($id = false, $table = null, $ds = null) {
            parent::__construct($id, $table, $ds);
            $list = parent::find('all', array('contain' => array(
                    'OtherModelA.name', 'OtherModelB.name')));
            if( !empty( $list) ) { //just in case there are no results
                    $this->virtualFields['name'] = sprintf("'%s - %s'",$list[0]['ProductionCompany']['name'],$list[0]['Musical']['name']);
                    $this->displayField = 'name';
            }
    }
编辑:当数据库完全为空时我发现了一些错误,所以我添加了一个条件并将displayField移动到构造函数中。