从Rails控制器返回必要的数据

时间:2016-02-14 15:09:35

标签: ruby-on-rails ruby hash

我希望能够从控制器返回一些数据,这样我就可以使用gon gem在JavaScript中创建一个折线图。

我有两种模式:

account:  id[PK, int], name[string], credit[boolean], active[boolean]
balance: id[PK, int], account_id[FK, int], balance[decimal], date[date]

class Account < ActiveRecord::Base
  has_many :balances
end

class Balance < ActiveRecord::Base
  belongs_to :account
end

对于&#34;余额&#34;中的所有日期,我想返回活跃的帐户总和&#34; t&#34;活跃的地方是&#34; f&#34;和差异。

这是一些示例数据:

Account.create(name: 'Natwest', active: 't', credit: 'f')
Account.create(name: 'Cash', active: 't', credit: 'f')
Account.create(name: 'Capital One CC', active: 't', credit: 't')
Balance.create(account_id: '1', balance: '100', date: '31/10/2015')
Balance.create(account_id: '1', balance: '500', date: '30/11/2015')
Balance.create(account_id: '1', balance: '50', date: '31/12/2015')
Balance.create(account_id: '2', balance: '500', date: '30/09/2015')
Balance.create(account_id: '2', balance: '240', date: '31/10/2015')
Balance.create(account_id: '2', balance: '50', date: '30/11/2015')
Balance.create(account_id: '3', balance: '200', date: '30/09/2015')
Balance.create(account_id: '3', balance: '150', date: '31/10/2015')
Balance.create(account_id: '3', balance: '140', date: '30/11/2015')

这些是预期结果:

- 30/09/2015:
    active: 500
    inactive: 200
    difference: 300
- 31/10/2015:
    active: 340
    inactive: 150
    difference: 190
- 30/11/2015:
    active: 550
    inactive: 140
    difference: 410
- 31/12/2015:
    active: 50
    inactive: 0
    difference: 50

我认为我需要创建一个哈希来实现这一点,我可以按升序返回日期,如下所示,但我不确定如何返回activeinactivedifference值。

@test = Hash[
  Balance.joins(:account).order(date: :asc).group_by(&:date)
]

1 个答案:

答案 0 :(得分:1)

您可以使用:

  def hash_template
    Hash.new do |k, v|
      k[v] = Hash.new { |k1,v1| k1[v1] = 0 }
    end
  end

Balance.joins(:account)
        .order(date: :asc)
        .group_by(&:date)
        .each_with_object(hash_template) do |stats, memo|
  date = stats.first
  users = stats.second
  memo[date][:active] = users.select { |b| b.account.active }.sum(&:balance)
  memo[date][:inactive] = users.select { |b| !b.account.active }.sum(&:balance)
  memo[date][:difference] = memo[date][:active] - memo[date][:inactive]
end
#=>
{Wed, 30 Sep 2015=>{:active=>700.0, :inactive=>0, :difference=>700.0},   
 Sat, 31 Oct 2015=>{:active=>490.0, :inactive=>0, :difference=>490.0},
 Mon, 30 Nov 2015=>{:active=>690.0, :inactive=>0, :difference=>690.0},
 Thu, 31 Dec 2015=>{:active=>50.0, :inactive=>0, :difference=>50.0}}