我有一个事件数据库。我创建了一个模型函数来检索基于城市,类型,子类型,开始和结束日期的事件。
它工作正常(大部分),但是天啊,这是一个值得一读的代码。有没有更好的方法来做到这一点?(这是一个很多代码,但不难理解我在做什么):
我的一些联想
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)
我的“getEvents”函数(在事件模型中):
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;
}
**加分:**我在StackOverflow (here)上也有一个关于这个函数的问题--试图弄清楚如何让它返回多个日期,而不是每个事件只返回一个。
1条答案
按热度按时间oxiaedzo1#
只要正确设置关联并执行普通的(递归的)
find()
即可。如果希望对检索到的关联数据进行更多的控制,请使用ContainableBehavior。如果您在某些相关模型上有条件要求您将其他表联接到主查询中,这是一个不同的主题,有许多方法可以实现它(搜索SO或询问特定问题)。为此,手动联接可能是合适的。但是,您不需要仅为了检索相关数据而手动联接表。