【发布时间】:2011-09-16 10:09:03
【问题描述】:
试图弄清楚如何在 CakePHP 中构建一个查询,在那里我可以选择 X 和 Y 日期(用户输入的日期)之间的所有事件。
问题在于Event 的表格中没有日期。
Event hasMany Schedule
Schedule belongsTo Event
Schedule hasMany Date
Date belongsTo Schedule
-
Events table:活动详情 - 名称、地点、描述...等 -
Schedules table:带有重复选项的开始和结束日期 -
Dates table:根据Schedules中的数据创建的事件的实际日期
所以 - 我实际上需要选择在 X 和 Y 日期之间至少有一个日期条目的任何事件。
我还需要能够显示带有事件数据的日期。
编辑(修订):
我已经尝试过了,但无论日期如何,它似乎都在检索事件,但只有在日期在范围内时才检索日期信息:
$this->Event->Behaviors->attach('Containable');
$events = $this->Event->find('all', array(
'limit'=>5,
'order'=>'Event.created DESC',
'contain' => array(
'Schedule' => array(
'fields'=>array(),
'Date' => array(
'conditions'=>array(
'start >=' => $start_date,
'start <=' => $end_date,
)
)
)
),
));
*澄清一下 - Date.start 和 Date.end 始终是相同的 Date - 它们还包括一个时间(两个日期时间字段) - 因此我要检查两者的“开始”。
我尝试过使用可包含,我已经尝试过 unbind/bindModel..etc - 我一定是做错了什么或偏离了轨道。
要记住的一点 - 一旦我弄清楚如何根据日期获取事件,我还需要添加其他条件,例如事件类型等等 - 不确定这是否会影响答案.
更新:
这是我正在使用的东西,它似乎有效 - 也看起来很丑 - 有什么想法吗?:
function getEvents($opts = null) {
//$opts = limit, start(date), end(date), types, subtypes, subsubtypes, cities
$qOpts['conditions'] = array();
//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
$qOpts['limit'] = 10;
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'];
//date conditions
array_push($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('OR'=>array('Venue.city_id'=>$city_id, 'Restaurant.city_id'=>$city_id)));
}
array_push($qOpts['conditions'], $cityConditions);
}
}
//event types conditions
//$opts['event_types'] = array('1');
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('EventTypesEvents.event_type_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('EventSubTypesEvents.event_sub_type_id' => $event_sub_type_id));
}
array_push($qOpts['conditions'], $eventSubTypeConditions);
}
}
//event sub sub types conditions
if(isset($opts['event_sub_sub_types'])) {
if(is_array($opts['event_sub_sub_types'])) {
$eventSubSubTypeConditions['OR'] = array();
foreach($opts['event_sub_sub_types'] as $event_sub_sub_type_id) {
array_push($eventSubSubTypeConditions['OR'], array('EventSubSubTypesEvents.event_sub_sub_type_id' => $event_sub_sub_type_id));
}
array_push($qOpts['conditions'], $eventSubSubTypeConditions);
}
}
$this->recursive = 2;
$data = $this->find('all', array(
'contain' => array(
'Restaurant' => array(
'fields' => array('id', 'name', 'slug', 'address', 'GPS_Lon', 'GPS_Lat', 'city_id'),
'City' => array(
'fields' => array('id', 'name', 'url_name'),
),
),
'Venue' => array(
'fields' => array('id', 'name', 'slug', 'address', 'GPS_Lon', 'GPS_Lat', 'city_id'),
'City' => array(
'fields' => array('id', 'name', 'url_name')
)
),
'Schedule' => array(
'fields' => array('id', 'name'),
'Date' => array(
'fields' => array('start', 'end'),
'conditions' => array(
'Date.start >=' => $qOpts['start'],
'Date.start <=' => $qOpts['end'],
),
),
),
'EventType' => array(
'fields' => array('id', 'name', 'slug'),
),
'EventSubType' => array(
'fields' => array('id', 'name', 'slug'),
),
'EventSubSubType' => array(
'fields' => array('id', 'name', 'slug'),
),
),
'joins' => array(
array(
'table' => $this->Schedule->table,
'alias' => 'Schedule',
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'Schedule.event_id = Event.id',
),
),
array(
'table' => $this->Schedule->Date->table,
'alias' => 'Date',
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'Date.schedule_id = Schedule.id',
),
),
array(
'table' => $this->EventTypesEvent->table,
'alias' => 'EventTypesEvents',
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'EventTypesEvents.event_id = Event.id',
),
),
array(
'table' => $this->EventSubTypesEvent->table,
//'table' => 'event_sub_types_events',
'alias' => 'EventSubTypesEvents',
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'EventSubTypesEvents.event_id = Event.id',
),
),
array(
'table' => $this->EventSubSubTypesEvent->table,
'alias' => 'EventSubSubTypesEvents',
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'EventSubSubTypesEvents.event_id = Event.id',
),
),
),
'conditions' => $qOpts['conditions'],
'limit' => $qOpts['limit'],
'group' => 'Event.id'
));
return $data;
}
【问题讨论】:
-
Dave,我正在查看您的更新。当然有一些方法可以避免使用 Containable AND 手动连接,并且仍然可以获得您想要的结果。我会调查一下,然后再回复你。但我对你所有的 OR 条件有点困惑,我不确定你想从数据库中获取什么数据。
-
另外:餐厅、场地和活动之间的关系是什么?
-
@bfavaretto - 求任何帮助 - 我快疯了。 “OR”允许用户选择他们想要将结果缩小到的列表事件类型。即——我只想看“体育”、“电影”和“户外”——所以我用“或”来表示
eventType必须是这些类型之一。与subTypes和@ 相同987654331@...等Event belongsTo VenueEvent belongsTo Restaurant(基本上,这两个地点都可以举行活动 - 只是在不同的桌子上) -
好的@Dave,我已经进行了一些测试,现在我明白了发生了什么。现在我将编辑我的原始答案以获取详细信息。
-
@bfavaretto - 老实说,我迫不及待想看看你想出了什么。
标签: mysql cakephp associations cakephp-1.3