неопределенный ключ метода для nil: NilClass при вызове метода gem - PullRequest
1 голос
/ 20 марта 2020

Я пытаюсь вызвать метод из драгоценного камня, который я создал, но продолжаю получать ошибку, указанную в заголовке. Я посмотрел на ошибку, но до сих пор не знаю, почему это происходит. Когда я запускаю файл в командной строке, он работает отлично. Все, что я хочу сделать, это заполнить метод пользовательским вводом и отобразить результат на моей странице индекса. Я запускаю следующую команду в командной строке:

irb -rubygems 

require 'unit_converter'

UnitConverter::Weight.new.conversions(1, :kg)

Вывод меняется в зависимости от того, что я набираю, но, например, вывод для этого будет:

["2.20462pounds", "0.157473stone"]

Это только когда Я пытаюсь связать его с моим файлом erb, чтобы получить упомянутую ошибку. Воспроизвести ошибку Это метод, который я создаю в моем файле sizes_controller:

def unit_converter
    @input1 = params[:value]
    @input2 = params[:unit]
    @result = UnitConverter::Weight.new.conversions(@input1.to_i , @input2)
    end

И в моем индексе. html .erb файл У меня есть такая форма:

  <%= form_tag "/validate" do %>
    <%= text_field_tag :value %>
    <%= text_field_tag :unit %>
    <%= submit_tag "Search" %>
    <% end %>
    <%= @result %>

И это мои маршруты, чтобы связать все воедино

 get '/check', :controller=>'measurements', :action=>'index'
  post '/validate', :controller=>'measurements', :action=>'unit_converter'

Это драгоценный камень, который я использую, и метод преобразования:

module UnitConverter

    class ConversionError < StandardError
    end

    class Weight
    # lookup table
    CONVERSIONS = {
      kg: {
        pounds: 2.20462,
        stone: 0.157473,
      },
      pounds: { 
        kg: 0.453592,
        stone: 0.0714286
      },
      stone: {
        kg: 6.35029,
        pounds: 14
      }
    }

    def convert(value, from, to:)
      raise ConversionError, "Value is not numeric" unless value.is_a? Numeric
      raise ConversionError, "Value #{value} is not positive" unless value >= 0
      "#{value * conversion_ratio(from, to) }#{to.to_s}"
    end

    def conversions(value, unit)
        CONVERSIONS[unit].keys.map do |other_unit|
          convert(value, unit, to: other_unit)
        end
      end

    private
    def conversion_ratio(from, to)
      begin
        CONVERSIONS.fetch(from).fetch(to)
      rescue KeyError
        raise ConversionError, "Cannot convert #{from.to_s} to #{to.to_s}"
      end
    end
  end
  end

Моя полная трассировка стека:

**unit_converter (0.0.0) lib/unit_converter.rb:32:in `conversions'
app/controllers/measurements_controller.rb:9:in `unit_converter'
actionpack (6.0.2.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.0.2.1) lib/abstract_controller/base.rb:196:in `process_action'
actionpack (6.0.2.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.0.2.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.0.2.1) lib/active_support/callbacks.rb:135:in `run_callbacks'
actionpack (6.0.2.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.0.2.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.0.2.1) lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
activesupport (6.0.2.1) lib/active_support/notifications.rb:180:in `block in instrument'
activesupport (6.0.2.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.0.2.1) lib/active_support/notifications.rb:180:in `instrument'
actionpack (6.0.2.1) lib/action_controller/metal/instrumentation.rb:32:in `process_action'
actionpack (6.0.2.1) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
activerecord (6.0.2.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.0.2.1) lib/abstract_controller/base.rb:136:in `process'
actionview (6.0.2.1) lib/action_view/rendering.rb:39:in `process'
actionpack (6.0.2.1) lib/action_controller/metal.rb:191:in `dispatch'
actionpack (6.0.2.1) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.0.2.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.0.2.1) lib/action_dispatch/routing/route_set.rb:837:in `call'
rack-pjax (1.1.0) lib/rack/pjax.rb:12:in `call'
remotipart (1.4.4) lib/remotipart/middleware.rb:32:in `call'
warden (1.2.8) lib/warden/manager.rb:36:in `block in call'
warden (1.2.8) lib/warden/manager.rb:34:in `catch'
warden (1.2.8) lib/warden/manager.rb:34:in `call'
rack (2.2.2) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.2) lib/rack/etag.rb:27:in `call'
rack (2.2.2) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.2) lib/rack/head.rb:12:in `call'
actionpack (6.0.2.1) lib/action_dispatch/http/content_security_policy.rb:18:in `call'
rack (2.2.2) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.2) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/cookies.rb:648:in `call'
activerecord (6.0.2.1) lib/active_record/migration.rb:567:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.0.2.1) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (6.0.2.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
web-console (4.0.1) lib/web_console/middleware.rb:132:in `call_app'
web-console (4.0.1) lib/web_console/middleware.rb:28:in `block in call'
web-console (4.0.1) lib/web_console/middleware.rb:17:in `catch'
web-console (4.0.1) lib/web_console/middleware.rb:17:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
railties (6.0.2.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (6.0.2.1) lib/rails/rack/logger.rb:26:in `block in call'
activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:80:in `block in tagged'
activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:28:in `tagged'
activesupport (6.0.2.1) lib/active_support/tagged_logging.rb:80:in `tagged'
railties (6.0.2.1) lib/rails/rack/logger.rb:26:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.2.2) lib/rack/method_override.rb:24:in `call'
rack (2.2.2) lib/rack/runtime.rb:22:in `call'
activesupport (6.0.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.2.2) lib/rack/sendfile.rb:110:in `call'
actionpack (6.0.2.1) lib/action_dispatch/middleware/host_authorization.rb:83:in `call'
webpacker (4.2.2) lib/webpacker/dev_server_proxy.rb:23:in `perform_request'
rack-proxy (0.6.5) lib/rack/proxy.rb:57:in `call'
railties (6.0.2.1) lib/rails/engine.rb:526:in `call'
puma (4.3.1) lib/puma/configuration.rb:228:in `call'
puma (4.3.1) lib/puma/server.rb:681:in `handle_request'
puma (4.3.1) lib/puma/server.rb:472:in `process_client'
puma (4.3.1) lib/puma/server.rb:328:in `block in run'
puma (4.3.1) lib/puma/thread_pool.rb:134:in `block in spawn_thread'**

1 Ответ

1 голос
/ 20 марта 2020

Когда вы вызываете метод conversions из консоли, вы передаете символ :kg ... но когда метод вызывается в контроллере, он получает строку.

Так что вам просто нужно преобразовать единицу измерения в символ, так же, как вы конвертируете числовое значение в целое число:

@result = UnitConverter::Weight.new.conversions(@input1.to_i , @input2.to_sym)

Ошибка, которую вы получили, была b / c поиск в вашем Таблица преобразований, по сути, искала Conversions['kg'], которая возвращает ноль - отсюда и сообщение об ошибке «неопределенные ключи метода ...».

Другое решение состоит в использовании вспомогательного метода, который Rails добавляет к Hash класс: with_indifferent_access.

Если вы определите свою таблицу поиска следующим образом (я опускаю ее внутренности), то вы можете получить к ней доступ Hash либо с помощью клавиш String, либо с помощью клавиш Symbol и выполните @input2.to_sym не будет необходимости:

CONVERSIONS = {
 ...
}.with_indifferent_access
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...