问题似乎是您的哈希数组中键 :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。我仍然没有做的是创建一个控制器或任何视图。我通过 Rails 控制台执行了我的代码。因此,如果您复制我的代码并且它对您不起作用,那么问题可能就在控制器和视图中。
最终,关于这种散列/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