我有一个关于相关模型虚拟字段的脑力激荡器。我知道它有它的局限性,你可以在这里阅读:http://book.cakephp.org/2.0/en/models/virtual-fields.html#limitations-of-virtualfields。 但在我的具体情况下,我不能应用将virtualField属性从一个模型传递到另一个模型的理论(即使我读过这个主题:Using virtual fields in cakePHP 2.x)。
我会尽可能清楚地解释我的案例。
我有3张桌子可以在我的网站上进行导航:
菜单
网页
menu_page_links
可以将一个页面添加到多个菜单中,这就是我在菜单和页面之间建立链接表(MenuPageLink
)的原因。
class Menu extends AppModel
{
public $hasMany = array(
'MenuPageLink' => array(
'className' => 'MenuPageLink',
'foreignKey' => 'menu_id'
)
);
}
class Page extends AppModel
{
public $hasMany = array(
'MenuPageLink' => array(
'className' => 'MenuPageLink',
'foreignKey' => 'page_id'
)
);
}
class MenuPageLink extends AppModel
{
public $belongsTo = array(
'Menu',
'Page'
);
// to calculate the depth of every menu page link
public $virtualFields = array(
'depth' => 'COUNT(MenuPageLink.title) - 1'
);
}
现在在我的应用程序中,我想在每个页面上加载特定的菜单,例如"主要菜单"来自"菜单"表。
所以在AppController.php中,我提到树所需的模型('Menu'
,'Page'
和'MenuPageLink'
)如下:
public $uses = array(
'Menu',
'Page',
'MenuPageLink'
);
然后我得到属于我的特定菜单的菜单页面,ID为#" 2":
$menu = $this->MenuPageLink->find('all', array(
'fields' => array(
'MenuPageLink.id',
'MenuPageLink.title',
'MenuPageLink.plugin',
'MenuPageLink.controller',
'MenuPageLink.action',
'MenuPageLink.depth'
),
'joins' => array(
array(
'table' => $this->MenuPageLink->table,
'alias' => 'Parent',
'type' => 'LEFT',
'conditions' => array(
'MenuPageLink.lft BETWEEN Parent.lft AND Parent.rgt',
'MenuPageLink.menu_id' => 1
)
)
),
'conditions' => array(
'MenuPageLink.menu_id' => 2,
'MenuPageLink.lft >' => 1,
'MenuPageLink.deleted' => null
),
'group' => 'MenuPageLink.id',
'order' => array(
'MenuPageLink.lft ASC'
)
));
这是我调试$menu
变量时的结果:
array(
(int) 0 => array( 'MenuPageLink' => array( 'id' => '36', 'title' => 'Home', 'plugin' => '', 'controller' => 'home', 'action' => 'index', 'depth' => '1' ) ),
(int) 1 => array( 'MenuPageLink' => array( 'id' => '39', 'title' => 'News', 'plugin' => '', 'controller' => 'news_articles', 'action' => 'index', 'depth' => '1' ) ),
(int) 2 => array( 'MenuPageLink' => array( 'id' => '37', 'title' => 'About the park', 'plugin' => '', 'controller' => 'pages', 'action' => 'view', 'depth' => '1' ) ),
(int) 3 => array( 'MenuPageLink' => array( 'id' => '41', 'title' => 'Attractions', 'plugin' => '', 'controller' => 'attractions', 'action' => 'index', 'depth' => '2' ) ),
(int) 4 => array( 'MenuPageLink' => array( 'id' => '42', 'title' => 'Animals', 'plugin' => '', 'controller' => 'animals', 'action' => 'index', 'depth' => '2' ) ),
(int) 5 => array( 'MenuPageLink' => array( 'id' => '43', 'title' => 'Events', 'plugin' => '', 'controller' => 'events', 'action' => 'index', 'depth' => '2' ) ),
(int) 6 => array( 'MenuPageLink' => array( 'id' => '44', 'title' => 'Shows', 'plugin' => '', 'controller' => 'shows', 'action' => 'index', 'depth' => '2' ) ),
(int) 7 => array( 'MenuPageLink' => array( 'id' => '45', 'title' => 'History', 'plugin' => '', 'controller' => 'pages', 'action' => 'history', 'depth' => '2' ) ),
(int) 8 => array( 'MenuPageLink' => array( 'id' => '38', 'title' => 'Info', 'plugin' => '', 'controller' => 'pages', 'action' => 'view2', 'depth' => '1' ) ),
(int) 9 => array( 'MenuPageLink' => array( 'id' => '40', 'title' => 'Media', 'plugin' => '', 'controller' => 'pages', 'action' => 'media', 'depth' => '1' ) )
)
到目前为止一切顺利!
这就是我的问题。我只想选择深度为1的页面。我尝试创建一个新的'conditions'
参数:
$menu = $this->MenuPageLink->find('all', array(
'fields' => array(
'MenuPageLink.id',
'MenuPageLink.title',
'MenuPageLink.plugin',
'MenuPageLink.controller',
'MenuPageLink.action',
'MenuPageLink.depth'
),
'joins' => array(
array(
'table' => $this->MenuPageLink->table,
'alias' => 'Parent',
'type' => 'LEFT',
'conditions' => array(
'MenuPageLink.lft BETWEEN Parent.lft AND Parent.rgt',
'MenuPageLink.menu_id' => 1
)
)
),
'conditions' => array(
'MenuPageLink.menu_id' => 2,
'MenuPageLink.lft >' => 1,
'MenuPageLink.deleted' => null,
'MenuPageLink.depth' => 1 // <-- new rule in my query
),
'group' => 'MenuPageLink.id',
'order' => array(
'MenuPageLink.lft ASC'
)
));
在经历了很多令人头疼的事情后,我甚至尝试使用Model::query()
方法:
$this->MenuPageLink->query(
"SELECT
`MenuPageLink`.`id`
, `MenuPageLink`.`title`
, `MenuPageLink`.`lft`
, `MenuPageLink`.`rgt`
, `MenuPageLink`.`show`
, `MenuPageLink`.`deleted`
, (COUNT(`MenuPageLink`.`title`) - 1) AS `MenuPageLink`.`depth`
FROM
`blwfun`.`menu_page_links` AS `MenuPageLink`
LEFT JOIN
`blwfun`.`menus` AS `Menu`
ON
(`MenuPageLink`.`menu_id` = `Menu`.`id`)
LEFT JOIN
`blwfun`.`pages` AS `Page`
ON
(`MenuPageLink`.`page_id` = `Page`.`id`)
LEFT JOIN
`blwfun`.`menu_page_links` AS `Parent`
ON
(`MenuPageLink`.`lft` BETWEEN `Parent`.`lft` AND `Parent`.`rgt` AND `MenuPageLink`.`menu_id` = 1)
WHERE
`Parent`.`menu_id` = 1 AND `MenuPageLink`.`lft` > 1 AND `MenuPageLink`.`deleted` IS NULL AND `MenuPageLink`.`depth` = 1
GROUP BY
`MenuPageLink`.`id`
ORDER BY
`MenuPageLink`.`lft` ASC"
));
我一直收到sql错误,但我不知道如何解决它。正如我所说,我不知道如何将de CakePHP文档(http://book.cakephp.org/2.0/en/models/virtual-fields.html#limitations-of-virtualfields)中的理论应用于我的具体案例。 有没有人可以帮我解决这个问题?
你会成为我的英雄:)
答案 0 :(得分:0)
感谢AgRizzo,我将我的选择查询更改为此并且工作正常:
$menuLinks = $this->MenuPageLink->find('all', array(
'fields' => array(
'MenuPageLink.id',
'MenuPageLink.title',
'MenuPageLink.lft',
'MenuPageLink.rgt',
'MenuPageLink.plugin',
'MenuPageLink.controller',
'MenuPageLink.action',
'MenuPageLink.show',
'MenuPageLink.depth',
'MenuPageLink.deleted'
),
'joins' => array(
array(
'table' => $this->MenuPageLink->table,
'alias' => 'Parent',
'type' => 'LEFT',
'conditions' => array(
'MenuPageLink.lft BETWEEN Parent.lft AND Parent.rgt',
'MenuPageLink.menu_id' => 1
)
)
),
'conditions' => array(
'Parent.menu_id' => 1,
'MenuPageLink.lft >' => 1,
'MenuPageLink.deleted' => null
),
'group' => 'MenuPageLink.id HAVING (COUNT(MenuPageLink.title) - 1) <= 1',
'order' => array(
'MenuPageLink.lft ASC'
)
));
我希望它可以帮助有相同虚拟领域问题的人;)