Ruby上的轨道 - 哈希数组 - 基于钥匙显示值



我有一系列散列的哈希保存在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密钥相对应的值,但使用以下代码,但它给我一个no implicit conversion of Symbol into Integer错误…

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

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

update

哈希密钥和局部变量都被命名相同,这是令人困惑的,我将局部变量更改为 fin_year

&lt;%= fin_year.class%>正在生产String

&lt;%= @item.yearly_interest_totals.class%>正在生产Array

&lt;%= @item.yearly_interest_totals [0] [:financial_year] .class%>正在返回"无隐式转换符号到整数中"错误...

问题似乎是键键 :financial_year在您的哈希阵列中的值是字符串(例如" 2017年"),但是变量financial_year的值是fixnum/integer(例如,2017年)。尝试使它们保持一致,例如:

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

此处是从轨道控制台输出,比较两者:

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 > 

更新(02-20-2017)

我不完全了解Rails内部的区别在于您的问题来源,但是即使您执行@item.yearly_interest_totals[0].class并获得Hash,您似乎也无法使用Hash键访问该值(例如[:financial_year],[" financial_year"]等)。

挖掘后,我发现了这个:铁轨访问哈希值并且接受的答案使我尝试了JSON.parse,尽管使用.each而不是.detect,但我能够工作。这次,我在Rails 5应用程序中确实创建了Item型号,使用了Postgres,并播种了一个Item。我仍然没有做的是创建控制器或任何视图。我通过导轨控制台执行了代码。因此,如果您复制我的代码并且对您不起作用,则问题可能在控制器和视图中。

最终,关于此哈希/JSON的区别以及实施如何使其表现为一个或另一个。

app/models/item.rb

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

db/migrate/2017022021004_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

我不知道铁路5,但这也许会有所帮助,Rails 4,假设Financial_year是一个变量,我正确地理解了这个问题:

<% @item.yearly_interest_totals.each do |t| %>
<%= t['total'] == financial_year %>
<% end %>

最新更新