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 要求を処理するにはどうすればよいですか? または、その方法を知るために何を読むことができますか?

コンソールに返されたデータはどこで確認できますか (存在する場合)? これがまだ何かをしているのかどうかさえわかりませんが、フォームで「検索」をクリックすると、今のところ空白のページである検索ブック アクションに移動します。

私は全体の答えから遠く離れているかもしれませんが、これは初めてです。

4

3 に答える 3

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=>"ニュージャージー州バークレー ハイツ: Enslow Publishers, c2000.",
  :概要=>
   「人種差別に直面し、アメリカでの黒人の経験を描くことに専念した詩人の伝記。」}]

このコードは、複数のブロックを受け取る可能性があるという考えに基づいている<BookData>ため、ハッシュの配列を返します。用途が 1 つだけの場合:

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=>"ポール_ローレンス_ダンバー",
 :isbn=>"0766013502",
 :title=>"ポール ローレンス ダンバー",
 :titlelong=>"ポール ローレンス ダンバー: 詩人の肖像",
 :authorstext=>"キャサリン・リーフ",
 :publishertext=>"ニュージャージー州バークレー ハイツ: Enslow Publishers, c2000.",
 :概要=>
  「人種差別に直面し、アメリカでの黒人の経験を描くことに専念した詩人の伝記.」}
于 2012-12-14T16:34:40.350 に答える
1

ISBNdb 関連のコードを独自のモデルに移動して、コントローラーを簡素化することを強くお勧めします。これを行う良い方法の 1 つは、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 に答える
0

正しい方向への基本的なポインティングを探しているので、私が認識したいくつかのポイントを次に示します。

1) HTTP 経由でソースを取得するには、HTTP クライアントgem を使用するのが一般的です。Exconと過小評価されているHTTP クライアント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 に答える