0

这是我第一次尝试从 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 请求或者我可以阅读什么来了解如何处理?

在哪里可以查看控制台中返回的数据(如果有)?我什至不确定这是否正在做任何事情,但是在我的表单中单击“搜索”后,我被带到了 searchbook 操作,该操作目前是一个空白页面。

我可能离整个答案还有很长的路要走,但这是我第一次这样做。

4

3 回答 3

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 调用添加方法。这就是实践中的单一职责原则

于 2012-12-14T12:44:27.793 回答
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=>"保罗·劳伦斯·邓巴",
  :titlelong=>"保罗·劳伦斯·邓巴:诗人肖像",
  :authorstext=>"凯瑟琳礁",
  :publishertext=>"新泽西州伯克利高地:恩斯洛出版社,c2000。",
  :总结=>
   “一本直面种族主义并致力于描绘美国黑人经历的诗人的传记。”}]

此代码基于您可能会接收多个<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=>"保罗·劳伦斯·邓巴",
 :titlelong=>"保罗·劳伦斯·邓巴:诗人肖像",
 :authorstext=>"凯瑟琳礁",
 :publishertext=>"新泽西州伯克利高地:恩斯洛出版社,c2000。",
 :总结=>
  “一本直面种族主义并致力于描绘美国黑人经历的诗人的传记。”}
于 2012-12-14T16:34:40.350 回答
0

当您正在寻找正确方向的基本指示时,以下是我认可的几点。

1) 对于通过 HTTP 获取任何源,通常使用HTTP 客户端gem。我可以推荐Excon和被低估的HTTP Client gem,尽管你会发现更多的选项,例如在 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。它附带一个控制台,您始终可以通过浏览器与当前环境进行交互。

于 2012-12-13T13:52:21.483 回答