【问题标题】:Ruby on Rails - Array of Hashes - Display value based on keyRuby on Rails - 哈希数组 - 基于键显示值
【发布时间】:2017-07-09 04:40:23
【问题描述】:

我有一个哈希数组保存到 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\"}"
]

在这个页面上我还有一个变量&lt;%= fin_year %&gt;,它显示2017

我正在尝试在视图中显示与此 fin_year 键对应的值,使用以下代码,但它给了我一个 no implicit conversion of Symbol into Integer 错误......

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

有人能解释一下为什么我会收到这个错误吗?

更新

哈希键和局部变量都被命名为相同的名称令人困惑,我已将局部变量更改为fin_year

正在生成String

正在生成 Array

正在返回“没有将符号隐式转换为整数”错误...

【问题讨论】:

  • 这可能与financial_year 是一个变量和符号有关。尝试将变量更改为 fin_year 或其他内容。另外,&lt;%= financial_year.class %&gt;&lt;%= @item.yearly_interest_totals[0][:financial_year].class %&gt; 显示什么?
  • 另外,我可能会将t[:financial_year] 更改为t["financial_year"]。不知道为什么,但有时我觉得很奇怪。
  • @RyanK 绝对令人困惑-我已经更改了局部变量并在上面进行了更新。我还编辑了上面的内容以显示两者上的.class 给了我什么...
  • t[:financial_year]改成t["financial_year"]怎么样?

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    问题似乎是您的哈希数组中键 :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
    

    【讨论】:

    • 我刚刚更新了上面的内容,financial_year / fin_year 局部变量的类型似乎是字符串,但是哈希值返回了上面的错误。你以前见过这个吗?干杯
    • fin_year 变量是早先在 &lt;% @item.repayments.group_by… %&gt; 块中创建的。然后我在 fin_year 赋值后检查它的类类型,在这个 .group_by 块内......
    • 对此评论的注意事项 - 首先,由于我只是使用变量重新创建了您的问题,而不是像您一样设置模型和数据库,我无法确定问题是否与您的模型/数据库/迁移实现。其次,我建议的一些内容通过 Rails 4 而不是 5 进行了演示,但希望仍然适用。话虽如此,我假设您的 Item 类迁移具有以下内容: t.hstore :yearly_interest_totals, array: true。如果是这样,请查看这篇文章中标记为“查询”的部分:inopinatus.org/2013/07/12/using-arrays-of-hstore-with-rails-4
    • 在该帖子中创建一个类似于“where_any”的范围,然后在您的@item 上使用它,看看它是否返回您所需年份的总数。
    • 好的,我的列类型是 Array,而不是 Hstore。我按照您上面的示例进行操作,效果很好 - 感谢您的跟进!
    猜你喜欢
    • 1970-01-01
    • 2013-07-06
    • 2015-06-13
    • 2014-04-09
    • 2021-12-09
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多