In Yii, I need to add a "derived" column to any resultset from my model. The column doesn't actually exist in the database table.
For example, say I have an Activity
model. There are only two types of Activities: (1) Income, or (2) Expense.
If I want to add a column called income_total
or expense_total
(depending on what type of activity is being accessed), how would I do that?
Here's a working example of an Activity
model in Ruby on Rails (I'm basically wondering how to do the same thing, 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 points to the use of Virtual Attributes, this adds an attribute to each "row" of the resultset that I'm retrieving from the database.
If the Activity
model has a BELONGS_TO
relationship with Parent
, a Parent View may look like the following:
<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, it doesn't make sense for this Virtual Attribute to be accessed within the foreach() loop.
These Virtual Attributes that I want provide one "aggregated" value for the whole resultset, so I want to be able access it using $parent->activities->incomes_total
, like so:
<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 within the Activity model code to achieve this, or should I be thinking about this a different way?