在我的Rails應用程序中,我有users
誰可以有很多payments
。如何在Rails模型中更新實例變量?
class User < ActiveRecord::Base
has_many :invoices
has_many :payments
def year_ranges
...
end
def quarter_ranges
...
end
def month_ranges
...
end
def revenue_between(range, kind)
payments.sum_within_range(range, kind)
end
end
class Invoice < ActiveRecord::Base
belongs_to :user
has_many :items
has_many :payments
...
end
class Payment < ActiveRecord::Base
belongs_to :user
belongs_to :invoice
def net_amount
invoice.subtotal * percent_of_invoice_total/100
end
def taxable_amount
invoice.total_tax * percent_of_invoice_total/100
end
def gross_amount
invoice.total * percent_of_invoice_total/100
end
def self.chart_data(ranges, unit)
ranges.map do |r| {
:range => range_label(r, unit),
:gross_revenue => sum_within_range(r, :gross),
:taxable_revenue => sum_within_range(r, :taxable),
:net_revenue => sum_within_range(r, :net) }
end
end
def self.sum_within_range(range, kind)
@sum ||= includes(:invoice => :items)
@sum.select { |x| range.cover? x.date }.sum(&:"#{kind}_amount")
end
end
在我dashboard
鑑於我取決於用戶選擇了GET參數列出了ranges
總付款。用戶可以選擇years
,quarters
或months
。
class DashboardController < ApplicationController
def show
if %w[year quarter month].include?(params[:by])
@unit = params[:by]
else
@unit = 'year'
end
@ranges = @user.send("#{@unit}_ranges")
@paginated_ranges = @ranges.paginate(:page => params[:page], :per_page => 10)
@title = "All your payments"
end
end
的使用實例變量(@sum
)大大降低SQL的數量在這裏查詢,因爲該數據庫將不會越過命中爲相同的查詢一遍又一遍。
但問題是,當用戶創建,刪除或更改他的某個payments
時,這不會反映在@sum
實例變量中。那麼我該如何重置它?還是有更好的解決方案呢?
感謝您的任何幫助。
+1,很好的解決方法。雖然我會讓'sum_within_range'做所有使用SQL的計算(請參閱我的回答) –
@m_x ya通常情況會更好,但由於prev問題,我有一些bkgrnd。這個函數在相同的重疊範圍請求中被調用了很多次,所以我認爲最好在Rails中進行過濾。但如果不是這樣的話,你的解決方案更有意義:) – tihom
謝謝。當我複製你的確切代碼時,我仍然可以獲得大約80個SQL查詢。所以我將'includes(:invoice =>:items)'移動到'Payment'類的select方法的開頭,現在每頁只有大約10個SQL查詢(與之前相同,因此也很好),但是總渲染時間已經增加了很多,從大約300毫秒到大約3000毫秒。這絕對是太多了,我想知道它爲什麼。 – Tintin81