【问题标题】:Sinatra JSON.parse undefined method when moving helper to another file将帮助程序移动到另一个文件时的 Sinatra JSON.parse 未定义方法
【发布时间】:2014-11-05 05:12:19
【问题描述】:

我有一个路由助手,当它位于我的路由文件的“助手执行”块中时,它可以正常工作,但是当我将助手移动到我的 helpers.rb 文件时,我得到一个错误。这是助手:

def processPutRequest(patient_id, request, _class, foreign_key, route_fragment)
  p = Patient.find(patient_id)
  data = request.body.read
  puts 'request body' + data
  data = JSON.parse(data)
  host_with_port = request.host_with_port

  puts 'hash data: ' + data.inspect

  saveListData(params[:id], data, _class, foreign_key)

  url = {'url' => "http://#{host_with_port}/patients/#{params[:id]}#{route_fragment}"}.to_json
  Rack::Response.new(url)
end

这里是助手在路由文件中时的日志记录:

request body{"list_data":[{"id":8440,"value":"Removal of ear wax (procedure)"},{"id":9827,"value":"Foreign body in nose (disorder)"}]}
hash data: {"list_data"=>[{"id"=>8440, "value"=>"Removal of ear wax (procedure)"}, {"id"=>9827, "value"=>"Foreign body in nose (disorder)"}]}

当我将其移至帮助文件时:

request body{"list_data":[{"id":8440,"value":"Removal of ear wax (procedure)"},{"id":9827,"value":"Foreign body in nose (disorder)"}]}
NoMethodError - undefined method `parse' for Sinatra::JSON:Module:

我错过了一些非常简单的东西吗?

编辑,让调试器工作。路由文件中 request.body.read 之后的“数据”:

"{"list_data":[{"id":8440,"value":"Removal of ear wax (procedure)"},{"id":9827,"value":"Foreign body in nose (disorder)"}]}"

在帮助文件中:

"{"list_data":[{"id":8440,"value":"Removal of ear wax (procedure)"},{"id":9827,"value":"Foreign body in nose (disorder)"}]}"

所以内容看起来和我一模一样。我可以从字面上剪切和粘贴两个文件之间的这个方法,它在路由文件中工作正常,在帮助文件中未定义的方法解析失败。我猜我以某种方式错误地定义了该模块,或者有一个 dandling 或丢失的字符,但是 RubyMine 没有显示任何错误,并且该方法至少部分执行,因此该方法正在获取。

完整的帮助文件:

module Sinatra
  module DynFormat
    CONTENT_TYPES={'xml' => 'text/xml','json' => 'application/json'}

    def dynamicFormat(data,format=params[:format])
      content_type CONTENT_TYPES[format], :charset => 'utf-8'
      case format
        when 'xml'
          data.to_xml
        when 'json'
          data.to_json
      end
    end
  end
  helpers DynFormat

  module RouteHelpers
    def processPutRequest(patient_id, request, _class, foreign_key, route_fragment)
      p = Patient.find(patient_id)
      data = request.body.read
      puts 'request body' + data
      data = JSON.parse(data)
      host_with_port = request.host_with_port

      puts 'hash data: ' + data.inspect

      saveListData(params[:id], data, _class, foreign_key)

      url = {'url' => "http://#{host_with_port}/patients/#{params[:id]}#{route_fragment}"}.to_json
      Rack::Response.new(url)
    end

    def saveListData(patient_id, list_data, _class, foreign_key)
      p = Patient.find(patient_id)

      _class = eval _class

      list_data = list_data['list_data']
      list_data.each do |x|
         _class.create(:patient_id => patient_id, foreign_key => x['id'] )
      end
    end


  end
  helpers RouteHelpers

end

【问题讨论】:

  • 您是否在 app.rb 中添加“require './helpers'”?
  • 是的,helpers.rb 中的另一个助手正在工作
  • 你在使用来自 Sinatra contrib 的任何东西吗?特别是Sinatra::JSON,或者要求所有扩展名都带有require 'sinatra/contrib/all'
  • 有趣的是你刚才应该问...我正在评估两个文件中的表达式,看到 JSON 在两个文件中的评估不同。当我看到你的问题时,我查看了我的所有要求,并意识到我正在采购 json 和 sinatra/json。
  • 我是新手,所以我可能随着时间的推移添加了这些,而没有意识到已经存在。感谢您为我指明正确的方向。

标签: ruby json sinatra helpers


【解决方案1】:

当您将方法放入外部文件时,您将放入 Sinatra 命名空间下的模块中:

module Sinatra
  module DynFormat
    #...
  end

  module RouteHelpers
    def processPutRequest(patient_id, request, _class, foreign_key, route_fragment)
      # code that refers to JSON...
    end
  end
end

当您的方法调用JSON.parse 时,它最终会找到Sinatra::JSON 模块,而不是您想要的顶级JSON 模块,因此您会收到错误undefined method `parse' for Sinatra::JSON:Module

当您在主文件的helpers 块中包含该方法时,该方法未在Sinatra 模块下定义,因此JSON 指的是正确的顶级模块。

如果需要包含Sinatra::JSON,可以使用::显式引用顶层模块:

data = ::JSON.parse(data)

另外请注意,您不一定需要在 Sinatra 下定义您的帮助模块(尽管文档确实建议您这样做)。您可以将它们移出Sinata 模块,然后使用例如Sinatra.helpers RouteHelpers 将他们注册为助手。

【讨论】:

  • 感谢您的详细解释,特别是为什么外部文件的处理方式不同。
【解决方案2】:

我需要 json 和 sinatra/json。不知道为什么最后一个没有一直赢,但删除 sinatra/json 解决了这个问题。如果有其他问题,我会花时间在两者之间做出选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-20
    • 2011-04-14
    • 2011-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 2020-12-16
    相关资源
    最近更新 更多