【问题标题】:How can I add a derived column to my Yii model?如何将派生列添加到我的 Yii 模型中?
【发布时间】:2012-06-15 03:27:06
【问题描述】:

在 Yii 中,我需要在我的模型中的任何结果集中添加一个“派生”列。该列实际上并不存在于数据库表中。

例如,假设我有一个Activity 模型。只有两种类型的活动:(1) 收入,或 (2) 费用。

如果我想添加一个名为 income_totalexpense_total 的列(取决于访问的活动的类型),我该怎么做?

这是 Ruby on Rails 中 Activity 模型的一个工作示例(我基本上想知道如何在 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

2012-07-01 更新:

answer provided by Leonardo 指向 Virtual Attributes 的使用,这为我从数据库中检索的结果集的每个“行”添加了一个属性。

如果Activity 模型与Parent 具有BELONGS_TO 关系,则父视图可能如下所示:

<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>

但是,在 foreach() 循环中访问此虚拟属性是没有意义的。

我想要的这些虚拟属性为整个结果集提供一个“聚合”值,因此我希望能够使用 $parent-&gt;activities-&gt;incomes_total 访问它,如下所示:

<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>

我需要在 Activity 模型代码中做些什么来实现这一点,或者我应该以不同的方式考虑这一点?

【问题讨论】:

  • 我刚刚看到 Yii 也有一个 Named Scopes 的实现。所以我正在阅读。它可能会为我指明正确的方向。

标签: php activerecord model yii virtual-attribute


【解决方案1】:

我相信它与 Ruby 非常相似。 PHP 有神奇的方法,在 Yii 中由 CComponent(包括 CActiveRecord 在内的许多基类)实现。

简而言之,您可以在模型中执行此操作

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

并且,从控制器访问它

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

【讨论】:

  • 我不知道可以做到这一点。伟大的。 Yii 称之为“Virtual Attributes
  • 这有助于虚拟属性是特定于每个 CActiveRecord 实例的,但是我需要虚拟属性跨越整个结果集。我已更新问题以反映此详细信息。
【解决方案2】:

正如我在other answer 中发布的那样,您可以简单地使用统计关系。将父模型中的 STAT 关系指定为

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

类似

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

注意:更改属性名称 parent_idamount 在您的模型中

【讨论】:

  • 我尝试过使用它,但我需要将它放在 Activity 模型中而不是在 Parent 模型中,以便在 Activity actionIndex() 视图中,我也可以在那里检索总数。
  • @Turgs 我不清楚你在说什么。请准确说明您想要什么,以便我可以编辑我的答案
  • 与其将 STAT 关系放在 Parent 模型中,我需要在 Activity 模型中以某种方式定义它。几乎就像与自身的 STAT 关系。也就是说,我不喜欢这种 STAT 关系方法如何触发单独的数据库查询。我最终想要一种使用已检索到的所有数据的方法。
  • @Turgs 你对all the data that's already been retrieved 的判决有误。 Yii 在对象初始化时不会检索任何相关的模型。它仅在访问时检索它。而且我不知道如何与同一个班级建立 STAT 关系。也许是可能的
  • 我想我不是在初始化对象时尝试检索数据。我只是想要同一个类中的东西,所以它在该模型的视图中作为 CActiveDataProvider('Activity') 对象可用。尽管在初始化 Activity 模型时数据不可用,但它在在检索数据时可用。由于 PHP 的限制,也许我正在寻找的东西很难。这可以在 Ruby 中完成(如我的问题所示)使用“self”方法很容易。目前,在需要时使用简单的 foreach 进行 SUM 似乎是最简单的。
【解决方案3】:

我不知道如何在模型中做到这一点。

虽然处理更多,但一个选项或解决方法是向视图添加另一个 foreach() 循环,如下所示:

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

【讨论】:

    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2019-01-10
    • 1970-01-01
    相关资源
    最近更新 更多