Как я могу проанализировать JSON и записать эти данные в базу данных, используя Sinatra и DataMapper - PullRequest
3 голосов
/ 19 ноября 2010

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

Я отправляю моему приложению Sinatra файл json, который содержит простое сообщение ниже.

[ 
        { 
        title: "A greeting!",
        message: "Hello from the Chairman of the Board" 
         }
]

Оттуда у меня есть сообщение, которое я использую, чтобы взять параметры и записать их в базу данных sqlite

post '/note' do

    data = JSON.parse(params) #<---EDIT - added, now gives error.

    @note = Note.new    :title => params[:title],
                          :message =>  params[:message],
                          :timestamp => (params[:timestamp] || Time.now) 
    @note.save
end

Когда я отправляю сообщение, отметка времени и идентификатор сохраняются в базе данных, однако заголовок и сообщение равны нулю.

Чего мне не хватает?

Спасибо

Редактировать:

Теперь, когда я запускаю свое приложение и отправляю ему файл json, я получаю эту ошибку:

C: /Users/Norm/ruby/Ruby192/lib/ruby/1.9.1/webrick/server.rb: 183: в блоке в start_thread Ошибка типа: невозможно преобразовать хэш в строку

Редактировать 2: некоторый успех.

У меня есть вышеупомянутый json в файле test.json, в котором json будет опубликован. Для размещения файла я использовал HTTPClient:

require 'httpclient'

HTTPClient.post 'http://localhost:4567/note', [ :file => File.new('.\test.json') ]

Подумав еще немного, я подумал, что опубликовать файл было проблемой, поэтому я попытался отправить его другим способом. Пример ниже сработал, как только я изменил свой дескриптор записи / заметки на этот:

data = JSON.parse(request.body.read)

Мой новый send.rb

require 'net/http'

require 'rubygems'
require 'json'

@host = 'localhost'
@port = '4567'

@post_ws = "/note"

@payload ={
    "title" => "A greeting from...",
    "message" => "... Sinatra!"
  }.to_json

def post
     req = Net::HTTP::Post.new(@post_ws, initheader = {'Content-Type' =>'application/json'})
          #req.basic_auth @user, @pass
          req.body = @payload
          response = Net::HTTP.new(@host, @port).start {|http| http.request(req) }
           puts "Response #{response.code} #{response.message}:
          #{response.body}"
        end

thepost = post
puts thepost

Так что я все ближе. Спасибо за всю помощь.

1 Ответ

6 голосов
/ 19 ноября 2010

Sinatra не будет автоматически анализировать JSON для вас, но, к счастью, анализ JSON довольно прост:

Начните с требования, как обычно.require 'rubygems' если вы не используете Ruby 1.9 +:

>> require 'json' #=> true
>> a_hash = {'a' => 1, 'b' => [0, 1]} #=> {"a"=>1, "b"=>[0, 1]}
>> a_hash.to_json #=> "{"a":1,"b":[0,1]}"
>> JSON.parse(a_hash.to_json) #=> {"a"=>1, "b"=>[0, 1]}

Это использование в обе стороны для создания, а затем разбора JSON.Выходные данные IRB показывают, что хеш и встроенный массив были преобразованы в JSON, а затем проанализированы обратно в хеш.Вы должны быть в состоянии разбить это для ваших гнусных нужд.

Чтобы получить поля, мы разберем приведенный выше пример немного подробнее и представим, что мы получили JSON с удаленной стороны вашего соединения.Итак, received_json ниже - это поток входящих данных.Передайте его анализатору JSON, и вы получите хеш данных Ruby.Получите доступ к хешу, как обычно, и вы получите значения:

>> received_json = a_hash.to_json #=> "{"a":1,"b":[0,1]}"
>> received_hash = JSON.parse(received_json) #=> {"a"=>1, "b"=>[0, 1]}
>> received_hash['a'] #=> 1
>> received_hash['b'] #=> [0, 1]

Входящий JSON, вероятно, является параметром в вашем params[] хеше, но я не уверен, под каким ключом он будет скрываться, поэтому выЯ должен это выяснить.Он может называться 'json' или 'data', но это зависит от приложения.

Код вашей базы данных выглядит нормально и должен работать, если вы видите некоторые данные, записанные в него.Похоже, вам просто нужно получить поля из JSON.

...