This seems a ridiculously basic question to ask but I am just not grasping the way to harness ActiveRecord in Yii.
The basic setup (a single example which will inform many other instances):
model Record with id, slug, name, etc.
model recordDetail with id, slug, name, recordId, recordType, sort, startDate, endDate, etc.
I know relations are set up correctly because a). I used Gii for CRUD scaffolding and B). I have the administrative end of the application working in fine fashion, including filtering the recordDetail so that it only operates within the context of a Record passed in the URL (borrowed from the Agile Yii book). I also have slugs set up correctly to load a model into a view based on the slug rather than the id, for SEO purposes.
What I am trying to do now is create a “Featured Record” view that will load a single Record based on criteria found in the recordDetail model: recordType=‘Featured’, startDate < $now and endDate > $now ($now being a variable passed from a function that derives a DateTime value from time() and adjusts for setTimeZone. I figured that these criteria would give me values of a certain record type, which has started and has not ended, which combined with order=‘sort’ and limit=1 would give me a single record at the top of the sort list.
I understand that all I need to do is derive the recordId number from this table and pass it to a Record model using findByPk($recordId)). I just can’t seem to DO it. I am attaching a few code samples of various methods I’ve tried by researching forum threads, the Definitive Guide, and various other resources:
for reference, the getCurrentTime function that will pop up here and there:
public function getCurrentTime()
{
Yii::app()->setTimeZone("America/New_York");
$now = date("Y-m-d\TH:i:s\Z", time());
return $now;
}
I have tried a named scope from recordDetail model:
public function scopes()
{
return array(
'today'=>array(
'condition'=>"recordType='Featured' AND startDate < '".$this->getCurrentTime()."' AND endDate> '".$this->getCurrentTime()."'",
'order'=>'sort ASC',
'limit'=>1,
),
);
}
combined with this function in the RecordController:
public function loadTodayRecord($recordId)
{
$model = Record::model()->with('recordDetails:today','other related records)->findAll();
if($model===null)
throw new CHttpException(404,'The requested Record could not be found.');
return $model;
}
and then render the view with this function in RecordController:
public function actionFeatured($id)
{
$record=$this->loadTodayRecord(true);
$this->render('featured',array(
'model'=>$record,
));
}
I have also tried the more verbose form of eager loading:
$model = Record::model()->findAll(array(
'with'=>array(
'recordDetails'=>array(
'scopes'=>array(
'today',
),
),'other related tables'
),
));
with the same (lack of) result.
I have tried using CDbCriteria in RecordController as follows:
public function getTodayRecord()
{
$q='Featured';
$r=$this->getCurrentTime();
$criteria = new CDbCriteria;
$criteria->condition = 'recordType = :q AND startDate < :r AND endDate > :r';
$criteria->order = 'priority';
$criteria->limit = 1;
$criteria->params = array(':q'=>$q,':r'=>$r);
$model = RecordDetail::model()->findAll($criteria);
if(!empty($model)) {
return $model->recordId;
}
and then using that value to load the model:
public function loadTodayRecord($recordId)
{
$recordId = $this->getTodayRecord();
$model = Record::model()->with('recordDetails','other related records')->findByPK($recordId);
if($model===null)
throw new CHttpException(404,'The requested Record could not be found.');
return $model;
}
the actionFeatured function does not render that, either.
There have been other similar things I have tried but I don’t have all the various code snippets from all my other efforts, as they have been put up and taken down over the last 18 hours. They were very much like these, trying to filter my model using scopes, or find a way to pass the recordId into the model load.
Some of them returned a blank page, which left me unsure if the result was a null array, or an array with multiple values that could not be rendered singly. Trying to print_r various attributes, e.g. $model->name, gave no result either, and count($model->name) often returned 0. count($model) would give me a count of around 380, but print_r($model) just freezes the page on load. Oh, and sometimes I would get a Division By Zero error on variables that made calculations based on model attributes, further suggesting no proper returned values.
These more recent efforts have rendered the page with a 400 error, "Your request is invalid", which is a similar result to trying to do a Yii-standard actionView without passing an id in the URL. Adding an id in this instance returns the context error above: "The requested Record could not be found" but if I change the render to just a regular loadModel and put an id into the URL, the page renders correctly.
So I know the page is doing its job when it has an id to work with. I just can’t get it to go find the recordId I want and use that for the value.
I know I have gone on for a while but I wanted to provide whatever information I could. I have been at this problem for a while with no result and no direction on where to go next, and this is a critical project. If someone could point me in the right direction to get the result I need, I would appreciate it greatly.