为什么我会收到TypeError? (没有将String隐式转换为Hash)

时间:2018-03-30 13:09:10

标签: ruby-on-rails

我在rails 5的敏捷Web开发教程中的一些代码中使用number_to_currency方法。我收到以下错误:

TypeError in Store#index
    Showing C:/Sites/depot/app/views/store/index.html.erb where line #13 raised:

no implicit conversion of String into Hash
Extracted source (around line #13):

    <%= sanitize(product.description) %>
    <div class="price_line">
      <span class="price"><%= number_to_currency(product.price) %></span>
      <%= button_to t('.add_html'),
      line_items_path(product_id: product, locale: I18n.locale),
      remote: true %>

我理解错误的方式是number_to_currency方法需要一个数字并且正在获取一个字符串。我检查了迁移文件,product.price应该是小数。在rails控制台Product.first.price.class中提供类BigDecimal。而不是错误暗示的字符串。哈希在哪里发挥作用。为什么要尝试将字符串转换为哈希值。我不明白该方法中发生了什么。任何人都可以向我解释这个吗?

index.html.erb:

<p id="notice"><%= notice %></p>
<h1><%= t('.title_html') %></h1>


<% cache @products do %>
  <% @products.each do |product| %>
    <% cache product do %>
      <div class="entry">
        <%= image_tag(product.image_url) %>
        <h3><%= product.title %></h3>
        <%= sanitize(product.description) %>
        <div class="price_line">
          <span class="price"><%= number_to_currency(product.price) %></span>
          <%= button_to t('.add_html'),
          line_items_path(product_id: product, locale: I18n.locale),
          remote: true %>
        </div>
      </div>
    <% end %>
  <% end %>
<% end %>

从schema.rb

中摘录
  create_table "products", force: :cascade do |t|
    t.string   "title"
    t.text     "description"
    t.string   "image_url"
    t.decimal  "price"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

相关的日志条目:

=> Booting Puma
=> Rails 5.0.6 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
*** SIGUSR2 not implemented, signal based restart unavailable!
*** SIGUSR1 not implemented, signal based restart unavailable!
*** SIGHUP not implemented, signal based logs reopening unavailable!
Puma starting in single mode...
* Version 3.11.2 (ruby 2.2.6-p396), codename: Love Song
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Started GET "/cable" for 127.0.0.1 at 2018-03-30 14:06:21 +0100
  ActiveRecord::SchemaMigration Load (1.1ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:23 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
ProductsChannel is transmitting the subscription confirmation
ProductsChannel is streaming from products
Started GET "/orders/new" for 127.0.0.1 at 2018-03-30 14:06:25 +0100
Processing by OrdersController#new as HTML
  Cart Load (0.0ms)  SELECT  "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ?  [["id", nil], ["LIMIT", 1]]
   (0.0ms)  begin transaction
  SQL (3.0ms)  INSERT INTO "carts" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2018-03-30 13:06:25.693988"], ["updated_at", "2018-03-30 13:06:25.693988"]]
   (102.4ms)  commit transaction
  LineItem Exists (1.0ms)  SELECT  1 AS one FROM "line_items" WHERE "line_items"."cart_id" = ? LIMIT ?  [["cart_id", 35], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Filter chain halted as :ensure_cart_isnt_empty rendered or redirected
Completed 302 Found in 446ms (ActiveRecord: 112.3ms)


Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:40 +0100
Started GET "/cable" for 127.0.0.1 at 2018-03-30 14:06:40 +0100
ProductsChannel stopped streaming from products
Started GET "/cable" for 127.0.0.1 at 2018-03-30 14:06:40 +0100
Started GET "/" for 127.0.0.1 at 2018-03-30 14:06:40 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:40 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:40 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Processing by StoreController#index as HTML
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:40 +0100
  Cart Load (1.0ms)  SELECT  "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ?  [["id", 35], ["LIMIT", 1]]
ProductsChannel is transmitting the subscription confirmation
ProductsChannel is streaming from products
  Rendering store/index.html.erb within layouts/application
  Product Load (0.0ms)  SELECT "products".* FROM "products" ORDER BY "products"."title" ASC
  Rendered store/index.html.erb within layouts/application (1076.5ms)
Completed 500 Internal Server Error in 1315ms (ActiveRecord: 3.1ms)



ActionView::Template::Error (no implicit conversion of String into Hash):
    10:         <h3><%= product.title %></h3>
    11:         <%= sanitize(product.description) %>
    12:         <div class="price_line">
    13:           <span class="price"><%= number_to_currency(product.price) %></span>
    14:           <%= button_to t('.add_html'),
    15:           line_items_path(product_id: product, locale: I18n.locale),
    16:           remote: true %>

app/views/store/index.html.erb:13:in `block (3 levels) in _app_views_store_index_html_erb__666600258_62743356'
app/views/store/index.html.erb:7:in `block (2 levels) in _app_views_store_index_html_erb__666600258_62743356'
app/views/store/index.html.erb:6:in `block in _app_views_store_index_html_erb__666600258_62743356'
app/views/store/index.html.erb:5:in `_app_views_store_index_html_erb__666600258_62743356'
  Rendering C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout
  Rendering C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (13.9ms)
  Rendering C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (8.0ms)
  Rendering C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.0ms)
  Rendered C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (3326.8ms)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-03-30 14:06:55 +0100
ProductsChannel stopped streaming from products

1 个答案:

答案 0 :(得分:0)

试试这个

<%= number_to_currency(product.price.to_f) %>

而不是

<%= number_to_currency(product.price) %>

希望它对你有用。