这是我第一次尝试从API获取数据,并将数据输出到视图。
我想将ISBN编号放入搜索表单,然后使用http://isbndb.com/获取该特定图书的数据。这就是我到目前为止所做的:
控制器:
require 'open-uri'
class BookController < ApplicationController
def searchbook
resp = open("http://isbndb.com/api/books.xml?access_key=#{'API KEY HERE'}&results=texts&index1=isbn&value1=#{params[:isbn]}")
doc = Nokogiri.XML(resp.read)
# ... process response here
end
end
形式:
<%= form_tag({:controller => 'book', :action => 'searchbook'}, {:method => 'get'}) do |select| %>
<%= label_tag :isbn, "Enter ISBN Number" %>
<%= text_field_tag :isbn, params[:isbn] %>
<%= submit_tag "Search" %>
<% end %>
要返回的XML
<?xml version="1.0" encoding="UTF-8"?>
<ISBNdb server_time="2005-07-29T03:02:22">
<BookList total_results="1" page_size="10" page_number="1" shown_results="1">
<BookData book_id="paul_laurence_dunbar" isbn="0766013502">
<Title>Paul Laurence Dunbar</Title>
<TitleLong>Paul Laurence Dunbar: portrait of a poet</TitleLong>
<AuthorsText>Catherine Reef</AuthorsText>
<PublisherText publisher_id="enslow_publishers">Berkeley Heights, NJ: Enslow Publishers, c2000.</PublisherText>
<Summary>A biography of the poet who faced racism and devoted himself to depicting the black experience in America.</Summary>
<Notes>"Works by Paul Laurence Dunbar": p. 113-114. Includes bibliographical references (p. 124) and index.</Notes>
<UrlsText></UrlsText>
<AwardsText></AwardsText>
</BookData>
</BookList>
</ISBNdb>
如何处理XML请求或我可以阅读哪些内容以了解如何处理?
在哪里可以查看控制台中返回的数据(如果有)?我甚至不确定这是否正在做任何事情,但是当我点击我的表格中的“搜索”时,我将被带到搜索本行动,这是一个空白页面。
我可能距离整个答案还有很长的路要走,但这是我第一次这样做。
答案 0 :(得分:1)
我强烈建议您将ISBNdb相关代码移动到自己的模型来简化控制器。一个好方法是通过HTTParty:
class ISBNdb
include HTTParty
base_uri "http://isbndb.com/api"
@key = "API_KEY_HERE"
def self.get_book(isbn)
params = {'value1' => isbn, 'results' => 'texts', 'index1' => 'isbn', 'access_key' => @key}
get('/books.xml', :query => params)['ISBNdb']['BookList']['BookData']
end
end
然后,在您的控制器中,您可以像这样使用它:
book = ISBNdb.get_book('1934356166')
puts book['Title'] #=> "Agile Web Development with Rails"
如您所见,HTTParty为您解析响应,因此您可以像哈希一样访问它。
此解决方案使您的控制器变得简单,并且还为其他API调用添加方法提供了方便的位置,如果您需要其他功能。这是实践中的Single Responsibility Principle。
答案 1 :(得分:1)
解析XML很简单:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="UTF-8"?>
<ISBNdb server_time="2005-07-29T03:02:22">
<BookList total_results="1" page_size="10" page_number="1" shown_results="1">
<BookData book_id="paul_laurence_dunbar" isbn="0766013502">
<Title>Paul Laurence Dunbar</Title>
<TitleLong>Paul Laurence Dunbar: portrait of a poet</TitleLong>
<AuthorsText>Catherine Reef</AuthorsText>
<PublisherText publisher_id="enslow_publishers">Berkeley Heights, NJ: Enslow Publishers, c2000.</PublisherText>
<Summary>A biography of the poet who faced racism and devoted himself to depicting the black experience in America.</Summary>
<Notes>"Works by Paul Laurence Dunbar": p. 113-114. Includes bibliographical references (p. 124) and index.</Notes>
<UrlsText></UrlsText>
<AwardsText></AwardsText>
</BookData>
</BookList>
</ISBNdb>
EOT
isbn_data = doc.search('BookData').map{ |book_data|
hash = {}
%w[ book_id isbn ].each do |p|
hash[p.downcase.to_sym] = book_data[p]
end
%w[ Title TitleLong AuthorsText PublisherText Summary ].each do |t|
hash[t.downcase.to_sym] = book_data.at(t).text
end
hash
}
pp isbn_data
哪个输出:
[{:book_id=>"paul_laurence_dunbar", :isbn=>"0766013502", :title=>"Paul Laurence Dunbar", :titlelong=>"Paul Laurence Dunbar: portrait of a poet", :authorstext=>"Catherine Reef", :publishertext=>"Berkeley Heights, NJ: Enslow Publishers, c2000.", :summary=> "A biography of the poet who faced racism and devoted himself to depicting the black experience in America."}]
此代码基于您可能正在接收多个<BookData>
块的想法,因此它返回一个哈希数组。如果您只使用一次:
hash = {}
book_data = doc.at('BookData')
%w[ book_id isbn ].each do |p|
hash[p.downcase.to_sym] = book_data[p]
end
%w[ Title TitleLong AuthorsText PublisherText Summary ].each do |t|
hash[t.downcase.to_sym] = book_data.at(t).text
end
pp hash
输出现在看起来像:
{:book_id=>"paul_laurence_dunbar", :isbn=>"0766013502", :title=>"Paul Laurence Dunbar", :titlelong=>"Paul Laurence Dunbar: portrait of a poet", :authorstext=>"Catherine Reef", :publishertext=>"Berkeley Heights, NJ: Enslow Publishers, c2000.", :summary=> "A biography of the poet who faced racism and devoted himself to depicting the black experience in America."}
答案 2 :(得分:0)
当你正在寻找正确方向的基本指向时,我认识到这几点。
1)对于通过HTTP获取任何源,通常使用 HTTP客户端 gem。我可以推荐Excon和被低估的HTTP Client宝石,不过你可以找到更多选项,例如在Ruby工具箱中。
2)要深入了解API响应,您可以例如只是引发输出结果的异常。我从RailsCast学到了这个技术。
# Example with Curb
http = Curl.get("http://www.google.com/")
body = http.body_str
# Raise an exception displaying the value you want to see
raise body.inspect
# or in nicely structured yaml format
raise body.to_yaml
你可以在任何地方使用这种技术,对我来说,当你想要查看你刚刚发送给某个控制器动作的参数时,它会派上用场。
甚至可以通过最近的better_errors gem来获得与返回值进行交互的方法(例如,尝试一些方法调用)。它随附一个控制台,您始终可以通过浏览器与当前环境进行交互。