ruby-on-rails - Ruby on Rails - 哈希数组 - 基于键显示值

标签 ruby-on-rails arrays ruby postgresql hash

我将一个哈希数组保存到 Rails 5 Postgres DB (Ruby 2.3.1)。我可以在我的 show.html.erb 上显示这个像这样的页面:

 <%= @item.yearly_interest_totals %>

这显示:

[
 "{:financial_year=>\"2017\", :total=>\"120.08\"}",
 "{:financial_year=>\"2018\", :total=>\"237.32\"}",
 "{:financial_year=>\"2019\", :total=>\"163.75\"}",
 "{:financial_year=>\"2020\", :total=>\"87.95\"}",
 "{:financial_year=>\"2021\", :total=>\"15.38\"}"
]

在这个页面上我还有一个变量 <%= fin_year %>显示 2017 .

我正在尝试显示与此 fin_year 对应的值在 View 中输入以下代码,但它给了我一个 no implicit conversion of Symbol into Integer错误……

<%= @item.yearly_interest_totals.detect do |t|
 t[:financial_year] == fin_year end [:total] %>

有人可以解释为什么我会收到此错误吗?

更新

散列键和局部变量的命名相同令人困惑,我已将局部变量更改为 fin_year .

<%= fin_year.class %> 正在生产 String

<%= @item.yearly_interest_totals.class %> 正在生产 Array

<%= @item.yearly_interest_totals[0][:financial_year].class %> 返回“没有将符号隐式转换为整数”错误...

最佳答案

问题似乎是您的散列数组中的键 :financial_year 的值是字符串(例如“2017”),但是变量 financial_year 的值> 是一个定数/整数(例如 2017)。尝试使它们一致以进行比较,例如:

<%= @item.yearly_interest_totals.detect do |t|
  t[:financial_year] == financial_year.to_s end [:total] %>

这是 Rails 控制台的输出,比较了两者:

Running via Spring preloader in process 15647
Loading development environment (Rails 4.2.7.1)

2.3.3 :001 > item_yearly_interest_totals = [{ financial_year: "2017", total: "120.08" }, { financial_year: "2018", total: "237.32" }, { financial_year: "2019", total: "163.75" }, { financial_year: "2020", total: "87.95" }, { financial_year: "2021", total: "15.38" }]
=> [{:financial_year=>"2017", :total=>"120.08"}, {:financial_year=>"2018", :total=>"237.32"}, {:financial_year=>"2019", :total=>"163.75"}, {:financial_year=>"2020", :total=>"87.95"}, {:financial_year=>"2021", :total=>"15.38"}]

2.3.3 :002 > financial_year = 2017
=> 2017

2.3.3 :003 > item_yearly_interest_totals.detect do |t|
2.3.3 :004 >      t[:financial_year] == financial_year end [:total]
NoMethodError: undefined method `[]' for nil:NilClass
  .
  .
  .

2.3.3 :005 > item_yearly_interest_totals.detect do |t|
2.3.3 :006 >      t[:financial_year] == financial_year.to_s end [:total]
=> "120.08"

2.3.3 :007 > 

更新(2017 年 2 月 20 日)

我不完全理解 Rails 中的区别所在或正在发生的地方是您问题的根源,但即使您执行 @item.yearly_interest_totals[0].class 并且您得到Hash,您似乎无法使用哈希键访问值(例如 [:financial_year]、["financial_year"] 等)。

经过一番挖掘,我发现了这个: Rails access hash value 接受的答案让我尝试了 JSON.parse,我能够开始工作,尽管使用的是 .each 而不是 .detect。这次我在 Rails 5 应用程序中创建了一个 Item 模型,使用了 Postgres,并植入了一个 Item。我还没有做的是创建一个 Controller 或任何 View 。我通过 Rails 控制台执行我的代码。因此,如果您复制我的代码但它对您不起作用,则问题可能出在 Controller 和 View 中。

最终,关于哈希/JSON 的区别以及实现如何导致它表现为其中之一,还有一些发现有待完成。

app/models/item.rb

class Item < ApplicationRecord
  validates :name, presence: true
end

db/migrate/20170220221004_enable_hstore_extension.rb

class EnableHstoreExtension < ActiveRecord::Migration
  def change
    enable_extension 'hstore'
  end
end

db/migrate/20170220221129_create_item.rb

class CreateItem < ActiveRecord::Migration[5.0]
  def change
    create_table :items do |t|
      t.string :name, null: false, index: { unique: true }
      t.hstore :yearly_interest_totals, array: true
      t.timestamps null: false
    end
  end
end

db/seeds.rb

Item.create(name: 'Sample Item', yearly_interest_totals: [{ financial_year: "2017", total: "120.08" }, { financial_year: "2018", total: "237.32" }, { financial_year: "2019", total: "163.75" }, { financial_year: "2020", total: "87.95" }, { financial_year: "2021", total: "15.38" }])

下面是在 Rails 控制台中执行的代码:

Running via Spring preloader in process 19764
Loading development environment (Rails 5.0.1)

2.4.0 :001 > @item = Item.first
Item Load (1.4ms)  SELECT  "items".* FROM "items" ORDER BY "items"."id" ASC LIMIT $1  [["LIMIT", 1]]
=> #<Item id: 1, name: "Sample Item", yearly_interest_totals: [{"total"=>"120.08", "financial_year"=>"2017"}, {"total"=>"237.32", "financial_year"=>"2018"}, {"total"=>"163.75", "financial_year"=>"2019"}, {"total"=>"87.95", "financial_year"=>"2020"}, {"total"=>"15.38", "financial_year"=>"2021"}], created_at: "2017-02-20 22:25:14", updated_at: "2017-02-20 22:25:14">
2.4.0 :002 > @item.class
=> Item(id: integer, name: string, yearly_interest_totals: hstore, created_at: datetime, updated_at: datetime)
2.4.0 :003 > @item.yearly_interest_totals.class
=> Array
2.4.0 :004 > @item.yearly_interest_totals[0].class
=> Hash

2.4.0 :005 > financial_year = 2017
=> 2017
2.4.0 :006 > financial_year.class
=> Integer

2.4.0 :007 > selected_year_interest_total = nil
=> nil
2.4.0 :008 > selected_year_interest_total.class
=> NilClass

2.4.0 :009 > @item.yearly_interest_totals.each do |t|
2.4.0 :010 >   puts JSON.parse(t["financial_year"]).class
2.4.0 :011 >   if JSON.parse(t["financial_year"]) == financial_year
2.4.0 :012?>     selected_year_interest_total = JSON.parse(t["total"])
2.4.0 :013?>   end
2.4.0 :014?> end
Integer
Integer
Integer
Integer
Integer
=> [{"total"=>"120.08", "financial_year"=>"2017"}, {"total"=>"237.32", "financial_year"=>"2018"}, {"total"=>"163.75", "financial_year"=>"2019"}, {"total"=>"87.95", "financial_year"=>"2020"}, {"total"=>"15.38", "financial_year"=>"2021"}]

2.4.0 :015 > selected_year_interest_total
=> 120.08
2.4.0 :016 > selected_year_interest_total.class
=> Float

关于ruby-on-rails - Ruby on Rails - 哈希数组 - 基于键显示值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42335454/

相关文章:

mysql - 如何在模型中存储日期?

python - 如何删除包含重复第一个元素的二维列表中的那些一维列表?

ruby - 创建具有均匀间隔值的数组

ruby-on-rails - Net/IMAP SSL 错误,2.1.5 和 2.2.1,但 2.1.0 和 2.1.2 有效

ruby - 由于 ruby​​-lang.org 布局更改(或永久性故障?),rbenv 安装失败

ruby-on-rails - Rails 5 失败测试 ActiveRecord::AssociationTypeMismatch

ruby-on-rails - 在特定 Controller 方法上切换 "ActionController::Parameters.action_on_unpermitted_parameters = :raise"?

ruby-on-rails - Rails 范围检查是否存在关联

arrays - 如何将结点中的值作为数组返回?

python - numpy 数组中的快速值交换