2014-11-05 4 views
1

У меня есть помощник маршрута, который отлично работает, когда он находится в блоке «помощники» в моем файле маршрута, но когда я перемещаю помощника в файл helpers.rb, Я получаю сообщение об ошибке. Вот помощник:Sinatra JSON.parse undefined метод при перемещении помощника в другой файл

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: 

Am Я пропустил что-то очень простое?

РЕДАКТИРОВАТЬ, отработал отладчик. "Данные" после того, как 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)"}]}" 

Таким образом, содержание выглядит идентично мне. Я могу буквально вырезать и вставлять этот метод между двумя файлами, он отлично работает в файле маршрутов, не работает с неопределенным анализом метода в файле помощников. Я предполагаю, что я каким-то образом определил этот модуль неправильно или имел дендлинг или отсутствующий символ, но 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 
+0

Вы добавляете "require" ./helpers "в app.rb? – scottxu

+0

Да, и еще один помощник в helpers.rb работает – LukeG

+0

Вы используете что-нибудь из Sinatra contrib? В частности ['Sinatra :: JSON'] (http://www.sinatrarb.com/contrib/json.html), или требуя всех расширений с' require 'sinatra/contrib/all''? – matt

ответ

0

Я требует как JSON и Синатра/JSON. Не знаю, почему последний не выиграл все время, но удаление синатра/json решило проблему. Если что-то еще сломается, я проведу время, решив между ними.

2

Когда вы кладете метод во внешнем файле, вы кладете в модуль под 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, чтобы зарегистрировать их в качестве помощников.

+0

Благодарим вас за подробное объяснение, особенно, почему внешний файл обрабатывался по-разному. – LukeG