比CakePHP中的-1递归手动联接更好的检索HABTM、HasMany…etc数据的方法?
我有一个事件数据库。我创建了一个模型函数来检索基于城市、类型、子类型、开始和结束日期的事件 它正在工作(大部分),但天啊,这是一个新的价值的代码。有更好的方法吗?(代码很多,但不难理解我在做什么): 我的一些联想:比CakePHP中的-1递归手动联接更好的检索HABTM、HasMany…etc数据的方法?,php,mysql,cakephp,join,has-and-belongs-to-many,Php,Mysql,Cakephp,Join,Has And Belongs To Many,我有一个事件数据库。我创建了一个模型函数来检索基于城市、类型、子类型、开始和结束日期的事件 它正在工作(大部分),但天啊,这是一个新的价值的代码。有更好的方法吗?(代码很多,但不难理解我在做什么): 我的一些联想: Event belongsTo Restaurant Event belongsTo Venue Restaurant belongsTo City Venue belongsTo City Event hasAndBelongsToMany EventType Event has
Event belongsTo Restaurant
Event belongsTo Venue
Restaurant belongsTo City
Venue belongsTo City
Event hasAndBelongsToMany EventType
Event hasAndBelongsToMany EventSubType
Event hasMany Schedule
Schedule hasMany Date
(and of course their belongsTo/hasMany counterparts are set up too)
function getEvents($opts) {
//$opts = limit, start, end, fields, types, subtypes, subsubtypes, cities
//dates
$qOpts['start'] = date('Y-m-d') . ' 00:00:00';
if(isset($opts['start'])) $qOpts['start'] = $opts['start'];
$qOpts['end'] = date('Y-m-d') . ' 23:59:59';
if(isset($opts['end'])) $qOpts['end'] = $opts['end'];
//limit
if(isset($opts['limit'])) $qOpts['limit'] = $opts['limit'];
//fields
$qOpts['fields'] = array('Event.id', 'Event.name', 'Event.slug', 'City.name', 'Date.start');
if(isset($opts['fields'])) $qOpts['fields'] = $opts['fields'];
//joins
$qOpts['joins'] = array(
array('table' => 'schedules',
'alias' => 'Schedule',
'type' => 'LEFT',
'conditions' => array(
'Event.id = Schedule.event_id',
)
),
array('table' => 'dates',
'alias' => 'Date',
'type' => 'LEFT',
'order' => 'Date.start ASC',
'conditions' => array(
'Date.schedule_id = Schedule.id',
),
),
array('table' => 'venues',
'alias' => 'Venue',
'type' => 'LEFT',
'conditions' => array(
'Event.venue_id = Venue.id',
)
),
array('table' => 'restaurants',
'alias' => 'Restaurant',
'type' => 'LEFT',
'conditions' => array(
'Event.restaurant_id = Restaurant.id',
)
),
array('table' => 'cities',
'alias' => 'City',
'type' => 'LEFT',
'conditions' => array(
'OR' => array(
'Venue.city_id = City.id',
'Restaurant.city_id = City.id',
),
)
),
array('table' => 'event_types_events',
'alias' => 'EventTypesEvent',
'type' => 'LEFT',
'conditions' => array(
'EventTypesEvent.event_id = Event.id',
)
),
array('table' => 'event_sub_types_events',
'alias' => 'EventSubTypesEvent',
'type' => 'LEFT',
'conditions' => array(
'EventSubTypesEvent.event_id = Event.id',
)
),
array('table' => 'event_types',
'alias' => 'EventType',
'type' => 'LEFT',
'conditions' => array(
'EventTypesEvent.event_type_id = EventType.id',
)
),
array('table' => 'event_sub_types',
'alias' => 'EventSubType',
'type' => 'LEFT',
'conditions' => array(
'EventSubTypesEvent.event_sub_type_id = EventSubType.id',
)
),
);
//date conditions
$qOpts['conditions'] = array(
"Date.start >=" => $qOpts['start'],
"Date.start <=" => $qOpts['end'],
);
//cities conditions
if(isset($opts['cities'])) {
if(is_array($opts['cities'])) {
$cityConditions['OR'] = array();
foreach($opts['cities'] as $city_id) {
array_push($cityConditions['OR'], array('City.id'=>$city_id));
}
array_push($qOpts['conditions'], $cityConditions);
}
}
//event types conditions
if(isset($opts['event_types'])) {
if(is_array($opts['event_types'])) {
$eventTypeConditions['OR'] = array();
foreach($opts['event_types'] as $event_type_id) {
array_push($eventTypeConditions['OR'], array('EventType.id'=>$event_type_id));
}
array_push($qOpts['conditions'], $eventTypeConditions);
}
}
//event sub types conditions
if(isset($opts['event_sub_types'])) {
if(is_array($opts['event_sub_types'])) {
$eventSubTypeConditions['OR'] = array();
foreach($opts['event_sub_types'] as $event_sub_type_id) {
array_push($eventSubTypeConditions['OR'], array('EventSubType.id'=>$event_sub_type_id));
}
array_push($qOpts['conditions'], $eventSubTypeConditions);
}
}
$this->recursive = -1;
$data = $this->find('all', $qOpts);
return $data;
}
我的“getEvents”函数(在事件模型中):
Event belongsTo Restaurant
Event belongsTo Venue
Restaurant belongsTo City
Venue belongsTo City
Event hasAndBelongsToMany EventType
Event hasAndBelongsToMany EventSubType
Event hasMany Schedule
Schedule hasMany Date
(and of course their belongsTo/hasMany counterparts are set up too)
function getEvents($opts) {
//$opts = limit, start, end, fields, types, subtypes, subsubtypes, cities
//dates
$qOpts['start'] = date('Y-m-d') . ' 00:00:00';
if(isset($opts['start'])) $qOpts['start'] = $opts['start'];
$qOpts['end'] = date('Y-m-d') . ' 23:59:59';
if(isset($opts['end'])) $qOpts['end'] = $opts['end'];
//limit
if(isset($opts['limit'])) $qOpts['limit'] = $opts['limit'];
//fields
$qOpts['fields'] = array('Event.id', 'Event.name', 'Event.slug', 'City.name', 'Date.start');
if(isset($opts['fields'])) $qOpts['fields'] = $opts['fields'];
//joins
$qOpts['joins'] = array(
array('table' => 'schedules',
'alias' => 'Schedule',
'type' => 'LEFT',
'conditions' => array(
'Event.id = Schedule.event_id',
)
),
array('table' => 'dates',
'alias' => 'Date',
'type' => 'LEFT',
'order' => 'Date.start ASC',
'conditions' => array(
'Date.schedule_id = Schedule.id',
),
),
array('table' => 'venues',
'alias' => 'Venue',
'type' => 'LEFT',
'conditions' => array(
'Event.venue_id = Venue.id',
)
),
array('table' => 'restaurants',
'alias' => 'Restaurant',
'type' => 'LEFT',
'conditions' => array(
'Event.restaurant_id = Restaurant.id',
)
),
array('table' => 'cities',
'alias' => 'City',
'type' => 'LEFT',
'conditions' => array(
'OR' => array(
'Venue.city_id = City.id',
'Restaurant.city_id = City.id',
),
)
),
array('table' => 'event_types_events',
'alias' => 'EventTypesEvent',
'type' => 'LEFT',
'conditions' => array(
'EventTypesEvent.event_id = Event.id',
)
),
array('table' => 'event_sub_types_events',
'alias' => 'EventSubTypesEvent',
'type' => 'LEFT',
'conditions' => array(
'EventSubTypesEvent.event_id = Event.id',
)
),
array('table' => 'event_types',
'alias' => 'EventType',
'type' => 'LEFT',
'conditions' => array(
'EventTypesEvent.event_type_id = EventType.id',
)
),
array('table' => 'event_sub_types',
'alias' => 'EventSubType',
'type' => 'LEFT',
'conditions' => array(
'EventSubTypesEvent.event_sub_type_id = EventSubType.id',
)
),
);
//date conditions
$qOpts['conditions'] = array(
"Date.start >=" => $qOpts['start'],
"Date.start <=" => $qOpts['end'],
);
//cities conditions
if(isset($opts['cities'])) {
if(is_array($opts['cities'])) {
$cityConditions['OR'] = array();
foreach($opts['cities'] as $city_id) {
array_push($cityConditions['OR'], array('City.id'=>$city_id));
}
array_push($qOpts['conditions'], $cityConditions);
}
}
//event types conditions
if(isset($opts['event_types'])) {
if(is_array($opts['event_types'])) {
$eventTypeConditions['OR'] = array();
foreach($opts['event_types'] as $event_type_id) {
array_push($eventTypeConditions['OR'], array('EventType.id'=>$event_type_id));
}
array_push($qOpts['conditions'], $eventTypeConditions);
}
}
//event sub types conditions
if(isset($opts['event_sub_types'])) {
if(is_array($opts['event_sub_types'])) {
$eventSubTypeConditions['OR'] = array();
foreach($opts['event_sub_types'] as $event_sub_type_id) {
array_push($eventSubTypeConditions['OR'], array('EventSubType.id'=>$event_sub_type_id));
}
array_push($qOpts['conditions'], $eventSubTypeConditions);
}
}
$this->recursive = -1;
$data = $this->find('all', $qOpts);
return $data;
}
函数getEvents($opts){
//$opts=限制、开始、结束、字段、类型、子类型、子类型、城市
//日期
$qOpts['start']=日期('Y-m-d')。'00:00:00';
如果(isset($opts['start'])$qOpts['start']=$opts['start']);
$qOpts['end']=日期('Y-m-d')。'23:59:59';
如果(isset($opts['end'])$qOpts['end']=$opts['end']);
//极限
如果(isset($opts['limit'])$qOpts['limit']=$opts['limit']);
//田地
$qOpts['fields']=array('Event.id','Event.name','Event.slug','City.name','Date.start');
if(isset($opts['fields'))$qOpts['fields]=$opts['fields'];
//加入
$qOpts['joins']=数组(
数组('table'=>'schedules',
'别名'=>'计划',
'类型'=>'左',
“条件”=>数组(
'Event.id=Schedule.Event_id',
)
),
数组('表'=>'日期',
'别名'=>'日期',
'类型'=>'左',
'order'=>'Date.start ASC',
“条件”=>数组(
'Date.schedule_id=schedule.id',
),
),
数组('表'=>'场馆',
“别名”=>“地点”,
'类型'=>'左',
“条件”=>数组(
'Event.vention_id=vention.id',
)
),
数组('表'=>'餐厅',
“别名”=>“餐厅”,
'类型'=>'左',
“条件”=>数组(
'Event.restaurant_id=restaurant.id',
)
),
数组('表'=>'城市',
“别名”=>“城市”,
'类型'=>'左',
“条件”=>数组(
'或'=>数组(
'vention.city_id=city.id',
'Restaurant.city_id=city.id',
),
)
),
数组('table'=>'event\u types\u events',
“别名”=>“EventTypesEvent”,
'类型'=>'左',
“条件”=>数组(
'EventTypesEvent.event_id=event.id',
)
),
数组('table'=>'event\u sub\u types\u events',
'别名'=>'事件子类型',
'类型'=>'左',
“条件”=>数组(
'eventSubjectSevent.event_id=event.id',
)
),
数组('表'=>'事件类型',
“别名”=>“事件类型”,
'类型'=>'左',
“条件”=>数组(
'EventTypesEvent.event\u type\u id=EventType.id',
)
),
数组('table'=>'事件子类型',
'别名'=>'事件子类型',
'类型'=>'左',
“条件”=>数组(
'EventSubsubjectEvent.event\u sub\u type\u id=EventSubType.id',
)
),
);
//日期条件
$qOpts['conditions']=数组(
“Date.start>=”=>$qOpts['start'],
“Date.startDave你这个白痴,只需正确设置你的关联,然后执行一个正常的(递归)
find()
。如果你想对检索到的关联数据有更多的控制权,请使用
如果某个关联模型的条件要求您将其他表连接到主查询中,那么这是一个不同的主题,有很多方法可以实现(搜索SO或询问特定问题)。为此,手动联接可能是合适的。不过,您不需要手动联接表来检索关联数据。很抱歉,无法获取关联。如果您的关联设置正确,如果您将
recursive
设置为something>0,则Cake将自动执行所有联接和获取操作。为什么要禁用所有这些自动联接?@deceze-要么a)我是个十足的白痴(很可能是这样),要么b)它返回了太多的数据,这让我走上了这条路,要么c)a和b都是。但是-你的建议让我觉得我可以使用正常的“查找”"并传递我想要的字段?如果它起作用,这对我来说将是一个巨大的失败!:)的确。:o)划掉所有代码,然后执行一个普通的查找。每个事件可能都会得到大量数据。如果你想限制它,请查看ContainableBehavior。如果你有更复杂的条件需要加入表,请询问更多具体的问题。@deceze-你想回答“Dave,你这个白痴,用一个普通的‘查找’!”这个问题吗?还是我应该删除这个问题?(非常感谢你引导我回到现实!)在用Cake的联想数小时试图弄清楚这一点后,我重新表述了以前的问题(使用containable…等)而且。到目前为止,唯一有希望工作的答案是使用类似于我在上面所做的事情。我试了又试,但如果不使用手动连接,就无法让它工作……等等。我希望听到我错了,因为我更愿意使用我建立的关联。