2014-01-30 2 views
0

Итак, у меня есть модель site(#id, name, start_date, end_date), которая может быть в pause(#id, site_id, start_date, end_date), и я хочу отслеживать паузы.Добавление расчетного поля с данными из другой таблицы

Я начал с добавления кнопки расширения на сайте CRUD, чтобы иметь возможность добавлять/удалять паузы. Работает как шарм.

Но теперь я хотел бы знать непосредственно в списке сайтов состояние каждого из них. Так что я начал, добавив новое поле выражения и просто проверить, если сайт находится в стадии разработки или нет:

$this->addExpression('state')->set('if(site.end_date IS NULL,"In Progress", if(now() < site.end_date, "In Progress", "Ended"))');

отлично работает! Но сейчас я не могу думать о методе, чтобы определить, является ли сайт находится в режиме паузы или нет, и на самом деле я не могу reproduice результат выше с помощью addExpression()->set(function($m, $q) {});

Edit:

Так пример, приведенный DarkSide работает как очарование, еще мне сейчас нужно смешать два результата в единственное поле state:

$this->addExpression('state')->set(function($model, $select) 
{ 
    // Is it ended ? 
    $ended = $select->expr('if(site.date_ended IS NULL,"In Progress", if(now() < site.date_ended, "In Progress", "Ended"))'); 

    // Is it in pause ? 
    $paused = $model->refSQL('Site_Pause') 
        ->count() 
        ->where('date_started', '<', $select->expr('now()')) 
        ->where('date_ended', '>', $select->expr('now()')); 

    if ($paused > 0) 
    return 'paused'; 
    return $ended; 
}); 

As $ модели-> refSQL() возвращает объект DSQL Я не могу использовать из if заявлений. Должен ли я попытаться сделать все в один раз SQL-запрос или попробовать, как указано выше, использовать операторы if, получая результаты из объекта Dsql?

ответ

0

Хорошо, получилось! Я отправляю здесь решение, если это необходимо по любому:

$this->addExpression('etat')->set(function($model, $select) { return ( $select->expr( 'IF ( site.date_ended IS NULL OR NOW() < site.date_ended, IF ( [f1] > 0, "Paused", "In Progress" ), "Ended" )' )->setCustom('f1', $model->refSQL('Site_Pause') ->count() ->where('date_started', '<', $select->expr('NOW()')) ->where('date_ended', '>', $select->expr('NOW()')) ) ); });

0

В Model_Site:

Плохой пример:

Я думаю, вы можете добавить все в подвыборки в наборе() метод как выражение, но это ни хорошо, ни целесообразным.

$this->addExpression('paused') 
    ->set("if((SELECT 1 FROM pause WHERE pause.start_date<now() AND (pause.end_date IS NULL OR pause.end_date>now())), 'yes', 'no') "); 

Лучше пример:

$this->addExpression('paused')->set(function($m, $q){ 
    return $m->refSQL('Pause') // Model_Pause 
     ->where('start_date', '<', $q->expr('now()')) 
     ->where('end_date', '>', $q->expr('now()')) // here you'll also need to use q->orExpr() to add case when end_date is null (see expression above in bad example) 
     ->count() 
     ; 
); 

Нечто подобное вы можете увидеть в моем планировщике дополнения моделей (last_status, last_run, next_status, next_run в Model_Task). Вот ссылка: https://github.com/DarkSide666/ds-addons/tree/master/Scheduler/lib/Model/Scheduler

Пожалуйста, имейте в виду, что все приведенные выше примеры полностью непроверены и предназначены только для того, чтобы дать вам представление.

+0

Thx я лучше понимаю теперь использовать $ т и $ д, см отредактированный вопрос на завершающем этапе я хотел бы достичь – Sluggogle

+0

я думаю, вы должны попробуйте сделать все в одном SQL, а затем вернуть его как DSQL. Вы можете попробовать ввести один DSQL в другой DSQL в качестве подзапроса. Может быть, это может помочь. Сегодня вечером я немного поспать, чтобы сделать хороший пример этого :) – DarkSide

Смежные вопросы