【问题标题】:Creating a hash in Rails在 Rails 中创建哈希
【发布时间】:2016-03-30 06:41:17
【问题描述】:

在我的 Rails 应用程序中,我尝试使用 Chart.js 根据从控制器传递的数据(在 gon gem 的帮助下)创建包含数据集的折线图。具体来说,我希望每个数据集都基于一个 account_id。

目前,控制器包含此代码,其中 gon.balances 是一个对象数组,包含以下字段 - account_id, balance, date...:

balances_controller.rb:

....
def index
  @balances = Balance.all.order(date: :desc)

  gon.balances = @balances
end
....

我想知道是否可以像下面的伪代码那样在控制器中动态创建变量,如果可以,如何?

  • 读取所有唯一的 Balance.account_id
  • 对于每个 Balance.account_id
    • 返回账户名(Account.name)
    • 与该 Balance.account_id 对应的所有 Balance.date 和 Balance.balance

所以实际上,我希望能够像这样返回一个对象数组:

{:balance1.account.name => [[balance1.date, balance1.balance],
                           [balance2.date, balance2.balance]],
:balance3.account.name  => [[balance3.date, balance3.balance]] }

更新:

在下面 Dileep Nandanam 的帮助下,我设法返回了按 account_id 排序的所有余额。

balances_controller.rb:

  def index
    @balances = Balance.all.order(date: :desc)

    @balancesSortedByAccountId = Hash[
      Balance.all.order(date: :desc).group_by(&:account_id).map{|acc_id, acc_details|
        ["acc_#{acc_id}".to_sym, acc_details.map(&:balance)]
      }
    ]

    gon.balances = @balances
    gon.balancesSortByAccId = @balancesSortedByAccountId
  end

提供这样的哈希:

{:acc_id1 => [balance1, balance2], :acc_id2 => [balance_3] }

如何修改它以提供如下所示的哈希:

{:balance1.account.name => [[balance1.date, balance1.balance],
                           [balance2.date, balance2.balance]],
:balance3.account.name  => [[balance3.date, balance3.balance]] }

我不确定如何返回名称,我尝试了以下方法来尝试为日期和余额创建数组,但这会导致两个单独的数组:

    @balancesSortedByAccountId = Hash[
      Balance.all.order(date: :desc).group_by(&:account_id).map{|acc_id, acc_details|
        ["acc_#{acc_id}".to_sym, [acc_details.map(&:date), acc_details.map(&:balance)]]
      }
    ]

【问题讨论】:

    标签: javascript ruby-on-rails arrays ruby hash


    【解决方案1】:

    您可以使用 account_id 对对象进行分组,以创建一个以 acc_ids 作为键、余额数组作为值的哈希。

    @balances = Hash[
      Balance.all.order(date: :desc).group_by(&:account_id).map{|acc_id, acc_details|
        ["acc_#{acc_id}".to_sym, acc_details.map(&:balance)]
      }
    ]
    

    会给你一个类似的哈希

    {:acc_id1 => [balance1, balance2], :acc_id2 => [balance_3] }
    

    你可以把它变成go变量

    gone.push(@balances)
    

    【讨论】:

    • 我在控制器中收到无方法错误。 ... '未定义的方法 `to_sym' for 1:Fixnum'
    • 查看编辑。 "acc_#{acc_id}" 将帮助您将一个消失的变量作为gone.acc_123 访问
    • 谢谢。这就说得通了。我已经更新了 OP,因为我想修改哈希以返回其他信息,例如每个余额的日期和帐户名称而不是 id。
    • 您可以简单地使用 [acc_details.account.name , acc_details.map(&:attributes)] 作为哈希的有序对,这样键将是一个包含帐户名称和值作为数组的字符串包含帐户详细信息的哈希值。
    • 试试 acc_details.first.account.name ,因为 acc_details 是一个同名的活动记录对象数组。
    【解决方案2】:

    您需要将 Rails 中的数据注入到您的 JavaScript 中。在您的示例中,您的 index.html.erb 可以通过在您打开 <script> 后立即添加类似于以下行的内容来修改以使其正常工作。

    var gon = gon || {}; gon.balances = <%= @balances.to_json %>
    

    您可以通过在模型中实现 as_json 方法来自定义 balances 集合的结构,这些方法返回包含您需要的值的散列。

    【讨论】:

    • 在我的 javascript 示例中,数据在 gon.balances 中可用,但是,在我的示例中,gon.balances 是一个包含 9 个对象的数组,其中一些对象具有相同的 account_id。我的问题是尝试将它们分组,以便每个 account_id 有一个对象。
    • @Bhav 与您提出的问题无关,但请查看 rails 文档中的 group_by
    猜你喜欢
    • 1970-01-01
    • 2011-09-20
    • 2011-10-20
    • 2018-12-21
    • 2014-02-14
    • 2022-11-12
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多