对于以下RubyOnRails代码,有没有办法将“利润”计算移出View并进入模型..所以可能有一个名为 total_income 和 total_expense <的属性/强>
型号 - transaction.rb
class Transaction < ActiveRecord::Base
attr_accessible :name, :amount, :category
scope :incomes, :conditions => { :category => 'Income' }
scope :expenses, :conditions => { :category => 'Expense' }
end
控制器 - transactions_controller.rb
class TransactionsController < ApplicationController
def index
@incomes = Transaction.incomes
@expenses = Transaction.expenses
@transaction = Transaction.new
end
查看 - index.html.erb
<pre>
<strong>Income</strong>
<% @incomes.each do |income| %>
<%= income.name %> - <%= number_to_currency((income.amount.nil? ? 0 : income.amount)) %>
<% end %>
<strong>Subtotal:</strong> <%= number_to_currency(@income_total = @incomes.sum(:amount)) %>
<strong>Expenses</strong>
<% @expenses.each do |expense| %>
<%= expense.name %> - <%= number_to_currency((expense.amount.nil? ? 0 : expense.amount)) %>
<% end %>
<strong>Subtotal:</strong> <%= number_to_currency(@expenses_total = @expenses.sum(:amount)) %>
<strong>Profit: <%= number_to_currency(@income_total - @expenses_total) %></strong>
</pre>
答案 0 :(得分:2)
对于最基本的更改,您只需将类方法添加到Transaction
即可class Transaction < ActiveRecord::Base
attr_accessible :name, :amount, :category
scope :incomes, :conditions => { :category => 'Income' }
scope :expenses, :conditions => { :category => 'Expense' }
def self.income_total
incomes.sum :amount
end
def self.expenses_total
expenses.sum :amount
end
end
class TransactionsController < ApplicationController
def index
@incomes = Transaction.incomes
@expenses = Transaction.expenses
@income_total = Transaction.income_total
@expenses_total = Transaction.expenses_total
@transaction = Transaction.new
end
答案 1 :(得分:1)
这些天我更喜欢将这些多个相互依赖的实例变量包装到一个新的演示者类中,类似于(未经测试):
class TransactionPresenter
attr_reader :income_total, :expenses_total
def initialize
@incomes = Transaction.incomes
@expenses = Transaction.expenses
end
def each_income(&block)
@incomes.each(&block)
end
def each_expense(&block)
@incomes.each(&block)
end
def income_total
@income_total ||= number_to_currency(@incomes.sum(&:amount))
end
def expenses_total
@expenses_total ||= number_to_currency(@expenses.sum(&:amount))
end
def name_and_amount(income_or_expense)
"#{income_or_expense.name} - #{number_to_currency((income.amount.nil? ? 0 : income.amount))}"
end
def profit
number_to_currency(income_total - expenses_total)
end
end
# controller
def index
@presenter = TransactionPresenter.new
end
# view
<pre>
<strong>Income</strong>
<% @presenter.each_income do |income| %>
<%= @presenter.name_and_amount %>
<% end %>
<strong>Subtotal:</strong> <%= @presenter.income_total %>
<strong>Expenses</strong>
<% @presenter.each_expense do |expense| %>
<%= @presenter.name_and_amount %>
<% end %>
<strong>Subtotal:</strong> <%= @presenter.expenses_total %>
<strong>Profit: <%= @presenter.profit %></strong>
</pre>