ActiveRecord relation "injection"?

Hi,

I’m wondering if it is possible to “force” some relations when instancing some model …

I’m using auditTrail extension, which has AuditTrail model.

Each AuditTrail record contains "model" and "model_id" (model_id is and id of "model" record).

I have "Plan" ActiveRecord class, which has following method:


/**

	 * @return AuditTrail

	 */	

	public function findRecentChanges($num = 10)

	{

		$crit = new CDbCriteria;

		$crit->limit = $num;

		$crit->addCondition("action = :action");

		$crit->addCondition("model = :model");

		$crit->addCondition("field = :field");

		$crit->params = array(

			'action' => 'SET',

			'model' => get_class($this),

			'field' => 'status'

		);

		return AuditTrail::model()->recently()->findAll($crit);		

	}

this returns me list of AuditTrail records for the Item records.

I’d like to have relation pointing to Item record from AuditTrail record.

I could use simply AuditTrail::relations:




'item' => array(self::BELONGS_TO, 'Item', 'model_id');



but it won’t solve the problem, just this single case.

I’d like to force relations when instantiating AuditTrail, since in most cases I’m not using AuditTrail directly - instead I’m adding findRecent for specific model…

any solutions?

I’ve managed to find temporary (hopefully) solution:




<?php 


class MAuditTrail extends AuditTrail

{

	// relation injection

	private $_relationModel = null;

	

	/**

	 * @return MAuditTrail

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);				

	}

	

	

	public function relationInjection($model, $doWith = true)

	{

		$this->_relationModel = $model;

		$this->refreshMetaData();

		if ($doWith)

			return $this->with('item');

		return $this;

	}

	

	public function relations()

	{

		$rels = array(

			'user' => array(self::BELONGS_TO, 'User', 'user_id')

		);

		

		if ($this->_relationModel)

			$rels['item'] = array(self::BELONGS_TO, $this->_relationModel, 'model_id');

		

		return $rels;

	}

}



usage:




return MAuditTrail::model()->relationInjection('Plan')->findAll();



the above code will return set of AuditTrail records, each of them having extra field named item, which is instance of related ‘Plan’ model.

Unfortunately the method requires to refresh model metadata, which might potentially be not optimal.

Hope to hear comment from someone knowing Yii internals if there’s better method…