CakePHP 3 级深度模型关联
我对 CakePHP 比较陌生,我对文档做得很好,但几周来我一直在试图找到解决这个问题的方法,但我似乎没有找到解决方案,我确信这很容易,也许甚至自动可行,但我只是不知道如何找到它(也许我不知道这类事情的行话)
我的模型结构是这样的:
<?php
class Trip extends AppModel {
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Start' => array(
'className' => 'Place',
'foreignKey' => 'start_id'
),
'End' => array(
'className' => 'Place',
'foreignKey' => 'end_id'
),
'Transport' => array(
'className' => 'Transport',
'foreignKey' => 'transport_id'
)
);
}
?>
<?php
class Place extends AppModel {
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id'
),
'State' => array(
'className' => 'State',
'foreignKey' => 'state_id'
),
'City' => array(
'className' => 'City',
'foreignKey' => 'city_id'
)
);
var $hasMany = array(
'PlaceStart' => array(
'className' => 'trip',
'foreignKey' => 'start_id',
'dependent' => false
),
'PlaceEnd' => array(
'className' => 'trip',
'foreignKey' => 'end_id',
'dependent' => false
)
);
}
?>
<?php
class State extends AppModel {
var $belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasMany = array(
'City' => array(
'className' => 'City',
'foreignKey' => 'city_id',
'dependent' => false
)
);
}
?>
......等等用户,城市,国家,和运输模型。
我想要实现的是当我搜索 Trip
时获取整个树的所有信息。
<?php
class TripController extends AppController {
function index() {
debug($this->Trip->find('first'));
}
}
输出
Array
(
[Trip] => Array
(
[id] => 6
[created] => 2010-05-04 00:23:59
[user_id] => 4
[start_id] => 2
[end_id] => 1
[title] => My trip
[transport_id] => 1
)
[User] => Array
(
[id] => 4
[name] => John Doe
[email] => [email protected]
)
[Start] => Array
(
[id] => 2
[user_id] => 4
[country_id] => 1
[state_id] => 1
[city_id] => 1
[direccion] => Lincoln Street
)
[End] => Array
(
[id] => 1
[user_id] => 4
[country_id] => 1
[state_id] => 1
[city_id] => 4
[address] => Fifth Avenue
)
[Transport] => Array
(
[id] => 1
[name] => car
)
)
这是问题: 如何在一次查询中获取树中的所有信息?
我想要类似
Array
(
[Trip] => Array
(
[id] => 6
[created] => 2010-05-04 00:23:59
[User] => Array
(
[id] => 4
[name] => John Doe
[email] => [email protected]
)
[Start] => Array
(
[id] => 2
[user_id] => 4
[Country] => Array
(
[id] => 1
[name] = Spain
)
[State] => Array
(
[id] => 1
[name] = Barcelona
)
[City] => Array
(
[id] => 1
[name] = La Floresta
)
[address] => Lincoln Street
)
[End] => (same as Start)
[title] => My trip
[Transport] => Array
(
[id] => 1
[name] => car
)
)
)
CakePHP 可以创建这种数据吗? 不仅适用于 $this->Model->find()
,也适用于 $this->paginate()
例如:
// filter by start
if(isset($this->passedArgs['start'])) {
//debug('isset '.$this->passedArgs['start']);
$start = $this->passedArgs['start'];
$this->paginate['conditions'][] = array(
'OR' => array(
'Start.address LIKE' => "%$start%",
'Start.State.name LIKE' => "%$start%",
'Start.City.name LIKE' => "%$start%",
'Start.Country.name LIKE' => "%$start%"
)
);
$this->data['Search']['start'] = $start;
}
这似乎是一个粗糙的问题但我确信这已经被广泛完成并记录下来,我真的很感激任何帮助。
I am relatively new to CakePHP, I am doing fine with the documentation, but I've been trying to find a way out to this problem for weeks and I don't seem to find the solution, I am sure it is easy and maybe even automagically doable, but I just don't know how to find it (maybe I don't know the jargon for these kind of things)
My model structure is like this:
<?php
class Trip extends AppModel {
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Start' => array(
'className' => 'Place',
'foreignKey' => 'start_id'
),
'End' => array(
'className' => 'Place',
'foreignKey' => 'end_id'
),
'Transport' => array(
'className' => 'Transport',
'foreignKey' => 'transport_id'
)
);
}
?>
<?php
class Place extends AppModel {
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id'
),
'State' => array(
'className' => 'State',
'foreignKey' => 'state_id'
),
'City' => array(
'className' => 'City',
'foreignKey' => 'city_id'
)
);
var $hasMany = array(
'PlaceStart' => array(
'className' => 'trip',
'foreignKey' => 'start_id',
'dependent' => false
),
'PlaceEnd' => array(
'className' => 'trip',
'foreignKey' => 'end_id',
'dependent' => false
)
);
}
?>
<?php
class State extends AppModel {
var $belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
var $hasMany = array(
'City' => array(
'className' => 'City',
'foreignKey' => 'city_id',
'dependent' => false
)
);
}
?>
... and so forth with User, City, Country, and Transport Models.
What I am trying to achieve is to get all the information of the whole tree when I search for a Trip
.
<?php
class TripController extends AppController {
function index() {
debug($this->Trip->find('first'));
}
}
Outputs
Array
(
[Trip] => Array
(
[id] => 6
[created] => 2010-05-04 00:23:59
[user_id] => 4
[start_id] => 2
[end_id] => 1
[title] => My trip
[transport_id] => 1
)
[User] => Array
(
[id] => 4
[name] => John Doe
[email] => [email protected]
)
[Start] => Array
(
[id] => 2
[user_id] => 4
[country_id] => 1
[state_id] => 1
[city_id] => 1
[direccion] => Lincoln Street
)
[End] => Array
(
[id] => 1
[user_id] => 4
[country_id] => 1
[state_id] => 1
[city_id] => 4
[address] => Fifth Avenue
)
[Transport] => Array
(
[id] => 1
[name] => car
)
)
Here is the question:
How do I get in one query all the information down the tree?
I would like to have something like
Array
(
[Trip] => Array
(
[id] => 6
[created] => 2010-05-04 00:23:59
[User] => Array
(
[id] => 4
[name] => John Doe
[email] => [email protected]
)
[Start] => Array
(
[id] => 2
[user_id] => 4
[Country] => Array
(
[id] => 1
[name] = Spain
)
[State] => Array
(
[id] => 1
[name] = Barcelona
)
[City] => Array
(
[id] => 1
[name] = La Floresta
)
[address] => Lincoln Street
)
[End] => (same as Start)
[title] => My trip
[Transport] => Array
(
[id] => 1
[name] => car
)
)
)
Can CakePHP create this kind of data?
Not only for $this->Model->find()
but also for $this->paginate()
as for example:
// filter by start
if(isset($this->passedArgs['start'])) {
//debug('isset '.$this->passedArgs['start']);
$start = $this->passedArgs['start'];
$this->paginate['conditions'][] = array(
'OR' => array(
'Start.address LIKE' => "%$start%",
'Start.State.name LIKE' => "%$start%",
'Start.City.name LIKE' => "%$start%",
'Start.Country.name LIKE' => "%$start%"
)
);
$this->data['Search']['start'] = $start;
}
It seems like a rough question but I am sure this is extensively done and documented, I'd really appreciate any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您似乎一切设置都正常。您所要做的就是将递归设置为 2,这将为您的数据提供一个额外的级别(假设您已正确设置所有关系)
You seem to have everything setup OK. All you should have to do is set the recursive to 2 and that should give you an extra level to your data (assuming that you have set up all the relations correctly)
如果您需要深入超过 2 个级别,或者如果您有很多对于这个特定问题不需要的第 2 级关联,则另一种更外科手术式的解决方案特别有用,那就是 可控制行为。这是 1.2.x 文档。如果您使用的是 v1.3.x,您可以在此处找到它。
An alternative, more surgical, solution that's particularly useful if you need to go deeper than 2 levels or if you have a lot of 2nd level associations that you don't need for this particular problem is the Containable Behavior. This is the 1.2.x documentation. If you're using v1.3.x, you'll find it here.