How can I add a derived column to my Yii model?

In Yii, I need to add a “derived” column to any result set from my model. The column does not actually exist in the database table.

For example, let's say I have an Activity model. There are only two types of activity: (1) Income or (2) Expenses.

If I want to add a column called income_total or expense_total (depending on what type of activity they are accessing), how would I do it?

Here is a working example of an Activity model in Ruby on Rails (I basically wonder how to do the same, but in Yii):

 class Activity < ActiveRecord::Base attr_accessible :name, :effective_at, :amount, :category scope :incomes, :conditions => { :category => 'Income' } scope :expenses, :conditions => { :category => 'Expense' } def self.incomes_total incomes.sum :amount end def self.expenses_total expenses.sum :amount end end 

Update 2012-07-01:

The answer provided by Leonardo indicates the use of Virtual Attributes , this adds an attribute to each "row" of the result set that I retrieve from the database.

If the Activity model has a BELONGS_TO relationship with Parent , the parent view may look like this:

 <h2><?php echo $parent->name; ?></h2> <ul> <?php foreach($portfolio->activities as $activity): ?> <li> <?php echo CHtml::link($activity->name, array('activity/view', 'id' => $activity->id)); ?> <?php echo $activity->amount; ?> <?php echo $activity->incomes_total; ?> </li> <?php endforeach; ?> </ul> 

However, this virtual attribute does not make sense for access in the foreach () loop.

These virtual attributes that I want provide one “aggregate” value for the entire result set, so I want to have access to it using $parent->activities->incomes_total , for example:

 <h2><?php echo $parent->name; ?></h2> <?php echo $parent->activities->incomes_total; ?> <ul> <?php foreach($portfolio->activities as $activity): ?> <li> <?php echo CHtml::link($activity->name, array('activity/view', 'id' => $activity->id)); ?> <?php echo $activity->amount; ?> </li> <?php endforeach; ?> </ul> 

What do I need to do in the code of the Activity model for this, or should I think about it differently?

+4
source share
3 answers

I find this to be similar to Ruby. PHP has magic methods that are implemented in Yii by CComponent (the base class of many, including CActiveRecord).

In short, you can do it in your model

  class Activity extends CActiveRecord { public function getIncome_Total() { // ... } } 

And to access it from the controller

 $activity = Activity::model->findByPk(1); $income_total = $activity->income_total; 
+3
source

I do not know how this can be done within the framework of the model.

Although this is more processing, an option or workaround is to add another foreach() to the view:

 $incomes_total = 0; foreach($parent->activities as $activity) $incomes_total += $activity->amount; echo $incomes_total; 
0
source

As I wrote in another answer . You can just use the stat relation. Specify the STAT relation in the parent model as

 'incomes_total'=>array(self::STAT, 'Activity', 'parent_id','select'=>'SUM(amount)','condition'=>"incomes_total.category='Income'") 

Similarly

 'expense_total'=>array(self::STAT, 'Activity', 'parent_id','select'=>'SUM(amount)','condition'=>"incomes_total.category='Expense'") 

NOTE. Change the attribute names parent_id and amount , as in your model

0
source

All Articles