Erstellen Sie ein Modell zum Speichern von Informationen aus der Google Books-API für eine intuitive Handhabung und Prüfung

Zielgruppe

—— So erstellen Sie ein Rails-Portfolio für Bücher

Was dieser Artikel erreicht

Rufen Sie Informationen aus der Google Books-API-ID ab und speichern Sie sie in der Klasse

pry(main)> @google_book = GoogleBook.new_from_id('c1L4IzmUzicC')

pry(main)> @google_book.title
=> "Practical Rails Plugins"

pry(main)> @google_book.authors
=> ["Nick Plante", "David Berube"]

pry(main)> @google_book.image
=> "http://books.google.com/books/content?id=c1L4IzmUzicC&printsec=frontcover&img=1&zoom=5&edge=curl&imgtk=AFLRE73ENsMYFOfY27vluLqgI1cO-b80lA7enoeZzzcDGEhA5NWIj3djHvd6gvP1zlKoMoC4V0_7fKVuIjWQDYVs4FrDjHvxoqtRUcxHZ9L7isRtsHc2Cs5iS6DPAQQcTT20Oseo9gq_&source=gbs_api"

Suchen Sie nach Schlüsselwörtern und geben Sie mehrere Objekte zurück

pry(main)> @google_books = GoogleBook.search('Rails')

pry(main)> @google_books[0].title
=> "Übungsschienen"

pry(main)> @google_books.last.authors
=> ["Sam Ruby", "Dave Thomas", "David Heinemeier Hansson"]

pry(main)> @google_books.map { |google_book| google_book.title }
=> ["Übungsschienen",
 "Selbststudium Ruby on Rails",
 "Schienen Rezept",
 "Ajax on Rails",
 "Ruby on Rails 4-Anwendungsprogrammierung",
 "Verwendung von Ruby on Rails 5 Praktische Methode zur Entwicklung von Rails-Anwendungen, die von Außendiensttechnikern gelehrt wird",
 "Ruby on Rails 5 Super Primer",
 "Agile Webanwendungsentwicklung mit Rails 3rd Edition",
 "JRuby on Rails Praktischer Entwicklungsleitfaden",
 "Agile Webanwendungsentwicklung mit Rails 4th Edition"]

pry(main)> @google_books.class
=> Array

Gespeicherte Informationen können in mehreren Tabellen gespeichert werden


pry(main)> @google_book = GoogleBook.new_from_id('wlNHDwAAQBAJ')

pry(main)> @google_book.title                                   
=> "Verwendung von Ruby on Rails 5 Praktische Methode zur Entwicklung von Rails-Anwendungen, die von Außendiensttechnikern gelehrt wird"

pry(main)> @google_book.authors
=> ["Tomoaki Ota", "Shota Terashita", "Ryo Tezuka", "Ayumi Munezo", "Recruit Technologies Co., Ltd."]

pry(main)> @google_book.save
=> true


pry(main)> @book = Book.last

pry(main)> @book.title
=> "Verwendung von Ruby on Rails 5 Praktische Methode zur Entwicklung von Rails-Anwendungen, die von Außendiensttechnikern gelehrt wird"

pry(main)> @book.authors[0].name
=> "Tomoaki Ota"

pry(main)> @book.authors.size
=> 5

pry(main)> @book.authors.class
=> Author::ActiveRecord_Associations_CollectionProxy


pry(main)> @author = Author.last

pry(main)> @author.name
=> "Recruit Technologies Co., Ltd."

Was in diesem Artikel zu schreiben

Erstellen Sie ein Google Book-Modell, in dem Informationen aus der Google Books-API gespeichert werden. Es gibt zwei Hauptvorteile:

Dieser Artikel beschreibt auch Anwendungsbeispiele und Tests mit Controller.

DB Design

In der Datenbank werden die folgenden Informationen zum Buch gespeichert:

--"Titel" --"Autor" --"Bild URL"

Natürlich können alle anderen Informationen in der Google Books-API abgerufen und gespeichert werden. In diesem Artikel ist zur Erläuterung die Menge der zu erfassenden Informationen gering.

ER-Diagramm

名称未設定ファイル.png

Bereiten Sie die Tabelle "Bücher" und die Tabelle "Autoren" vor. Da es für ein Buch mehrere Autoren geben kann, verwenden wir die Beziehung des Buches has_many Autoren.

Möglicherweise möchten Sie jedoch die repräsentativen Autoren anstelle aller Autoren auf einer Seite wie "Bücher auflisten" anzeigen. Bereiten Sie daher eine Spalte "is_representative" in der Autorentabelle vor.

Möglicherweise fragen Sie sich auch: "Wenn Sie Informationen von der Google Books-API abrufen möchten, müssen Sie diese nicht in Ihrer eigenen Datenbank haben." Die Geschichte des Entwurfs und des Versagens ist unten aufgeführt. Entwickelt, um diese Ressource nur mit der GoogleBooks-API zu erwerben, und fehlgeschlagen

Zusammenfassend kommen wir zu dem Schluss, dass sich die Informationen im Buch auch in Ihrer eigenen Datenbank befinden sollten.

Migrationsdatei

Wenn Sie eine Migrationsdatei erstellen, sieht diese folgendermaßen aus.

Büchertisch

db/migrate/20202020202020_create_books


class CreateBooks < ActiveRecord::Migration[5.2]
  def change
    create_table :books do |t|
      t.string :google_books_api_id, null: false
      t.string :title, null: false
      t.string :image
      t.date :published_at

      t.timestamps
    end

    add_index :books, :googlebooksapi_id, unique: true
  end
end

Die Google Books-API-ID ist immer erforderlich. Geben Sie daher "null: false" an. Da es unwahrscheinlich ist, dass die Google Books-API-ID dupliziert wird, geben Sie ihr einen eindeutigen Schlüssel.

Ein Buch ohne Titel wird als nicht vorhanden angesehen. Geben Sie daher "null: false" an.

Seien Sie im Gegenteil vorsichtig, wenn Sie für andere Informationen "null: false" angeben. Dies liegt daran, dass die Informationen von einer externen API stammen und einige Bücher möglicherweise nicht über diese Informationen verfügen. Dies kann dazu führen, dass "nicht in der Datenbank registriert werden kann".

Autorentabelle

db/migrate/20202020202021_create_authors


class CreateAuthors < ActiveRecord::Migration[5.2]
  def change
    create_table :authors do |t|
      t.references :book, foreign_key: true
      t.string :name, null: false
      t.boolean :is_representative, null: false

      t.timestamps
    end
  end
end

Methode zum Aufrufen der Google Books-API

Fügen Sie zunächst ein Modul hinzu, das die API unter "app / lib /" aufruft.

app/lib/google_books_api.rb


module GoogleBooksApi
  def url_of_creating_from_id(googlebooksapi_id)
    "https://www.googleapis.com/books/v1/volumes/#{googlebooksapi_id}"
  end
  #Rufen Sie die API-URL von der Google Books-API-ID ab

  def url_of_searching_from_keyword(keyword)
    "https://www.googleapis.com/books/v1/volumes?q=#{keyword}&country=JP"
  end
  #Rufen Sie die URL der zu suchenden API über das Schlüsselwort ab

  def get_json_from_url(url)
    JSON.parse(Net::HTTP.get(URI.parse(Addressable::URI.encode(url))))
  end
  #Rufen Sie die JSON-Zeichenfolge von der URL ab und erstellen Sie das JSON-Objekt
end

In diesem Artikel werden zwei Arten von Google Books-APIs verwendet.

https://www.googleapis.com/books/v1/volumes/:ID Sie können es über die URL erhalten. Die folgende URL ist ein Beispiel. https://www.googleapis.com/books/v1/volumes/aB4B13xGEv4C

Wenn Sie nicht wissen, welche Informationen Sie über die Google Books-API erhalten können, überprüfen Sie die obige URL. Sie können sehen, dass Sie Titel, Veröffentlichungsdaten, Kauflinks, ISBNs und mehr erhalten können.

https://www.googleapis.com/books/v1/volumes?q=search ?: Keyword Sie können es über die URL erhalten. Die folgende URL ist ein Beispiel. https://www.googleapis.com/books/v1/volumes?q=search?Rails

Wenn Sie weitere Spezifikationen der Google Books-API kennen möchten, lesen Sie bitte das offizielle Dokument. Getting Started

Ich verwende ein Juwel namens "adressierbar", um der URL zu entkommen. Fügen Sie der Gemfile das folgende Juwel hinzu und installieren Sie das Paket.

Gemfile


gem 'addressable'

Rails lädt übrigens automatisch app / ** / **. Rb. Daher können Sie die oben genannten drei Methoden in der Klasse verwenden, solange Sie "GoogleBooksApi" und "Include" in die Klasse aufnehmen, die Sie verwenden möchten.

Modell zum Speichern von Informationen

Erstellen Sie ein Modell, in dem Informationen aus der Google Books-API wie folgt als Objekt gespeichert werden.

app/models/google_book.rb


class GoogleBook
  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::Validations

  attribute :googlebooksapi_id, :string
  attribute :authors
  attribute :image, :string
  attribute :published_at, :date
  attribute :title, :string

  validates :googlebooksapi_id, presence: true
  validates :title, presence: true

  class << self
    include GoogleBooksApi

    def new_from_item(item)
      @item = item
      @volume_info = @item['volumeInfo']
      new(
        googlebooksapi_id: @item['id'],
        authors: @volume_info['authors'],
        image: image_url,
        published_at: @volume_info['publishedDate'],
        title: @volume_info['title'],
      )
    end

    def new_from_id(googlebooksapi_id)
      url = url_of_creating_from_id(googlebooksapi_id)
      item = get_json_from_url(url)
      new_from_item(item)
    end

    def search(keyword)
      url = url_of_searching_from_keyword(keyword)
      json = get_json_from_url(url)
      items = json['items']
      return [] unless items

      items.map do |item|
        GoogleBook.new_from_item(item)
      end
    end

    private

    def image_url
      @volume_info['imageLinks']['smallThumbnail'] if @volume_info['imageLinks'].present?
    end
  end

  def save
    return false unless valid?

    book = build_book
    return false unless book.valid?

    ActiveRecord::Base.transaction do
      book.remote_image_url = image if image.present?
      book.save
      authors.each.with_index do |author, index|
        author = book.authors.build(name: author)
        author.is_representation = index.zero?
        author.save
      end
    end
    true
  end

  def find_book_or_save
    if Book.find_by(googlebooksapi_id: googlebooksapi_id) || save
      Book.find_by(googlebooksapi_id: googlebooksapi_id)
    else
      false
    end
  end

  private

  def build_book
    Book.new(
      googlebooksapi_id: googlebooksapi_id,
      published_at: published_at,
      title: title,
    )
  end
end

Es ist lange her, lol Ich werde eins nach dem anderen erklären.

ActiveModel

  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::Validations

ActiveModel ist wie "ActiveRecord, das nicht mit der Datenbank funktioniert".

Active Model Basics-Rails-Handbuch

ActiveModel-Attribut

  attribute :googlebooksapi_id, :string
  attribute :authors
  (Folgendes wird weggelassen)

Sie können es verwenden, weil Sie "include" "ActiveModel :: Attributes" haben. Es wird angenommen, dass ein Array in "Autoren" enthalten sein wird, aber es scheint, dass es keinen Attributtyp gibt, der dem Array entspricht, daher wird dieser verwendet.

ActiveModel :: Attributes ist zu gut.

ActiveModel wird überprüft

  validates :googlebooksapi_id, presence: true
  validates :title, presence: true

Es gibt kein Buch ohne ID der Google Books-API und kein Buch ohne Titel (wie es scheint). Geben Sie also "validetes" ein. Wenn ein Buch ohne ID für die Google Books-API als Objekt gespeichert wird, kann es bei Verwendung der Methode "valid?" "False" zurückgeben. (Es wird später beschrieben, wird aber in der Methode "Speichern" verwendet.)

So definieren Sie eine Klassenmethode

  class << self

new_from_id ist eine Methode, die Sie als Klassenmethode wieGoogleBook.new_from_id ('c1L4IzmUzicC')verwenden möchten. Es gibt andere Möglichkeiten, eine Klassenmethode zu definieren, aber die Methode "class << slef" scheint empfohlen zu werden.

Grund für die Definition der Ruby-Klassenmethode mit der Klasse << self (Übersetzung)

Erstellen Sie eine Instanz aus einer ID

    def new_from_id(googlebooksapi_id)
      url = url_of_creating_from_id(googlebooksapi_id)
      item = get_json_from_url(url)
      new_from_item(item)
    end

Die Reihenfolge ist etwas falsch, aber ich werde new_from_id vor new_from_item erklären.

Sie können die Informationen (JSON) eines Buches als "Element" abrufen, indem Sie "url_of_creating_from_id" und "get_json_from_url" des oben genannten Moduls "Google Books Api" verwenden. Übergeben Sie dieses Element an new_from_item.

Erstellen Sie eine Instanz aus item

    def new_from_item(item)
      @item = item
      @volume_info = @item['volumeInfo']
      new(
        googlebooksapi_id: @item['id'],
        authors: @volume_info['authors'],
        image: image_url,
        published_at: @volume_info['publishedDate'],
        title: @volume_info['title'],
      )
    end

Wie Sie anhand des Inhalts der Google Books-API sehen können, befinden sich viele Informationen in "item [" volumeInfo "]. Definieren Sie die Informationen, die Sie abrufen möchten, und erstellen Sie mit new () eine Instanz. Nur image_url wird folgendermaßen implementiert.

Implementierung von image_url

    private

    def image_url
      @volume_info['imageLinks']['smallThumbnail'] if @volume_info['imageLinks'].present?
    end

Einige Bücher enthalten nicht "volume_info [" imageLinks "]. Wenn Sie also versuchen, es nur mit" volume_info ["imageLinks"] ["small Thumbnail"] zu verwenden, wird der Fehler "undefind" angezeigt. es gibt. Implementieren Sie wie oben, um die Ausgabe von "undefind" zu vermeiden.

Es ist auch unwahrscheinlich, dass diese "image_url" -Methode außerhalb der Klasse verwendet wird. Definieren Sie sie daher unter "privat".

Eine Klassenmethode, die Suchergebnisse als Gruppe von Instanzen zurückgibt

    def search(keyword)
      url = url_of_searching_from_keyword(keyword)
      json = get_json_from_url(url)
      items = json['items']
      return [] unless items

      items.map do |item|
        GoogleBook.new_from_item(item)
      end
    end

Wenn Sie die Google Books-API verwenden, die Suchergebnisse zurückgibt, erhalten Sie mehrere "Elemente". items hat die Form [item1, item2, item3, ...] als Array. Wenn Sie "new_from_item (item)" einzeln in der "map" -Methode ausführen, kann es in Form eines Arrays "[googlebook1, googlebook2, googlebook3, ...]" zurückgegeben werden.

Wenn das Schlüsselwort unangemessen ist, gibt die API, die die Suchergebnisse zurückgibt, keine "Elemente" zurück, sodass der Fehler "undefind" auch in diesem Fall auftritt. Daher wird durch Einfügen einer Zeile von "return [], sofern keine Elemente vorhanden sind, ein leeres Array zurückgegeben, wenn keine Elemente vorhanden sind."

Die Erklärung der save -Methode und der find_book_or_save -Methode bleibt weiterhin bestehen, aber ich denke, es ist einfacher zu verstehen, wie man sie zuerst in Controller verwendet, daher möchte ich zur Erklärung von Controller übergehen.

Anwendungsbeispiel in Controller

Ich denke, es gibt zwei Möglichkeiten, die GoogleBook-Klasse zu verwenden: "Suchbildschirm" und "Ressourcenregistrierung (erstellen)".

Routing

config/routes.rb


  resources :books, only: %i[create show], shallow: true do
    collection do
      get :search
    end
  end

Stellen Sie das obige Routing im Voraus ein. Ich werde die Erklärung weglassen, da sie nicht mit der Hauptleitung synchron ist.

Suchbildschirm Controller

app/controllers/books_controller.rb


class BooksController < ApplicationController
  def search
    @search_form = SearchBooksForm.new(search_books_params)
    books = GoogleBook.search(@search_form.keyword)
    @books = Kaminari.paginate_array(books).page(params[:page])
  end

  private

  def search_books_params
    params.fetch(:q, keyword: '').permit(:keyword)
  end
end

Entschuldigen Sie diesen Artikel, aber das Suchformular ist wie im folgenden Artikel implementiert. [Ruby on Rails] Suchschlüsselwörter mithilfe von Formularobjekten an den Controller senden

Übergeben Sie das empfangene Suchschlüsselwort ("@ search_form.keyword") an "GoogleBook.search" und erhalten Sie die Suchergebnisse als Array von Instanzen, die aus der "GoogleBook" -Klasse generiert wurden.

Danach ist es optional, aber ich wollte die Suchergebnisse in Kaminaris Paginierung anzeigen, also habe ich sie an Kaminari.paginate_array übergeben und verwendet.

Ressourcenregistrierung Controller Version 1 (NG-Beispiel, das nur mit herkömmlichen Methoden geschrieben wurde)

Folgendes möchte ich tun.

--Stellen Sie die Informationen, die Sie im "Google Book" -Modell hatten, im "Book" -Modell oder im "Author" -Modell wieder her

app/models/google_book.rb


class BooksController < ApplicationController
  def create
    google_book = GoogleBook.new_from_id(create_book_params[:googlebooksapi_id])
    @book = Book.build(
              googlebooksapi_id: google_book.googlebooksapi_id,
              published_at: google_book.published_at,
              title: google_book.title,
            )
    if @book.valid?
      @book.remote_image_url = google_book.image if google_book.image.present?
      @book.save
      google_book.authors.each.with_index do |author, index|
        @author = @book.authors.build(name: author)
        @author.is_representation = index.zero?
        @author.save
      end
      redirect_to @book
    else
      redirect_to search_books_path, danger: 'Fehler beim Anzeigen der Seite'
    end
  end

  private

  def create_book_params
    params.permit(:googlebooksapi_id)
  end
end

Es gibt jedoch verschiedene Probleme mit der obigen Implementierung.

Insbesondere das Problem des Fat Controllers muss behandelt werden. Erstens denke ich, dass der Prozess im Zusammenhang mit dem Speichern in dieser Datenbank der Prozess ist, für den das Google Book-Modell verantwortlich ist. Daher definieren wir die Speicherlogik als Instanzmethode von "GoogleBook".

Save -Methode, die das Speichern in mehreren Tabellen realisiert

app/models/google_book.rb


  def save
    return false unless valid?
    book = build_book

    ActiveRecord::Base.transaction do
      book.remote_image_url = image if image.present?
      book.save
      if authors.present?
        authors.each.with_index do |author, index|
          author = book.authors.build(name: author)
          author.is_representative = index.zero?
          author.save
        end
      end
    end
    true
  end

  private

  def build_book
    Book.new(
      googlebooksapi_id: googlebooksapi_id,
      published_at: published_at,
      title: title,
    )
  end

Damit es wie die "save" -Methode von "ActiveRecord" aussieht, möchte ich "true" zurückgeben, wenn das Speichern erfolgreich ist, und "false", wenn es fehlschlägt. Daher wird in einer Zeile von "return false, sofern nicht gültig?" "False" zurückgegeben, wenn dies mit "valid?" Fehlschlägt. Sie können bei Erfolg auch "true" zurückgeben, indem Sie am Ende des Erfolgs eine Zeile "true" einfügen.

Wenn Sie es in "ActiveRecord :: Base.transaction" einfügen, können Sie ein Rollback ausführen, wenn mehrere Ressourcen registriert sind und in der Mitte fehlschlagen. In diesem Fall können Sie die "book.save" in der ersten Hälfte stornieren, auch wenn in der zweiten Hälfte etwas mit "author.save" schief geht.

book.remote_image_url = image if image.present? ist die Logik zum Hochladen von Bildern mit Carrierwave. Da es von der Hauptzeile abweicht, werde ich diesmal die Erklärung weglassen.

author.is_representative = index.zero? Ist eine Zeile, um den Autor im ersten Index des Arrays autors zum "repräsentativen Autor" zu machen. Dies ist auch der Grund, warum wir "each.with_index" verwenden, um das Array zu drehen.

Ressourcenregistrierung Controller Version 2 (Doppelte Registrierung erfolgt)

app/controllers/books_controller.rb


class BooksController < ApplicationController
  def create
    google_book = GoogleBook.new_from_id(create_book_params[:googlebooksapi_id])
    if google_book.save
      @book = Book.find_by(googlebooksapi_id: google_book.googlebooksapi_id)
      redirect_to @book
    else
      redirect_to search_books_path, danger: 'Fehler beim Anzeigen der Seite'
    end
  end

  private

  def create_book_params
    params.permit(:googlebooksapi_id)
  end
end

Es ist ziemlich erfrischend, aber es gibt immer noch Probleme. Es besteht die Möglichkeit, dass die ID der Google Books-API dupliziert wird, dh dasselbe Buch wird registriert.

find_or_create_by geschmackvolle Implementierung

Was wir erreichen wollen, ist das Folgende.

--Wenn sich das Buch bereits in der Büchertabelle befindet, geben Sie das diesem Datensatz entsprechende Modell zurück

Wenn Sie von "ActiveRecord" sprechen, möchten Sie ein Verhalten nahe "find_or_create_by" erreichen. Implementieren Sie es als Instanzmethode von "GoogleBook" wie folgt als "find_book_or_save" -Methode.

app/models/google_book.rb


  def find_book_or_save
    if Book.find_by(googlebooksapi_id: googlebooksapi_id) || save
      Book.find_by(googlebooksapi_id: googlebooksapi_id)
    else
      false
    end
  end

Ressourcenregistrierung Controller Version 3 (abgeschlossen)

app/controllers/books_controller.rb


class BooksController < ApplicationController
  def create
    google_book = GoogleBook.new_from_id(create_book_params[:googlebooksapi_id])
    if (@book = google_book.find_book_or_save)
      redirect_to @book
    else
      redirect_to search_books_path, danger: 'Fehler beim Anzeigen der Seite'
    end
  end

  private

  def create_book_params
    params.permit(:googlebooksapi_id)
  end
end

Schreiben Sie einen Test mit RSpec

Es gibt drei Arten von Tests, die dieses Mal behandelt werden müssen.

Ich bin mir ein wenig unsicher, wie ich den Test schreiben soll, also freue ich mich darauf, lol darauf hinzuweisen

Testen der Methode zum Aufrufen der Google Books-API

spec/lib/google_books_api_spec.rb


require 'rails_helper'

describe GoogleBooksApi do
  let(:test_class) { Struct.new(:google_books_api) { include GoogleBooksApi } }
  let(:google_books_api) { test_class.new }

  it 'Sie können eine Art erhalten, die mehrere Daten zurückgibt, indem Sie auf die API klicken, um zu suchen' do
    url = google_books_api.url_of_searching_from_keyword('Rails')
    expect(google_books_api.get_json_from_url(url)['kind']).to eq 'books#volumes'
  end

  it 'Sie können eine Art erhalten, die bestimmte Daten zurückgibt, indem Sie auf die API klicken, um Buchinformationen von der ID abzurufen' do
    GOOGLE_BOOKS_API_ID_SAMPLE = 'aB4B13xGEv4C'.freeze
    url = google_books_api.url_of_creating_from_id(GOOGLE_BOOKS_API_ID_SAMPLE)
    expect(google_books_api.get_json_from_url(url)['kind']).to eq 'books#volume'
    expect(google_books_api.get_json_from_url(url)['id']).to eq GOOGLE_BOOKS_API_ID_SAMPLE
  end
end

Informationen zum Testen des Moduls finden Sie auf der folgenden Website.

[Ruby on Rails] Auch Anfänger möchten Unit-Tests von Methoden durchführen! !!

Modelltest von "Google Book"

Definieren Sie zunächst FactoryBot.

spec/factories/google_book.rb


FactoryBot.define do
  factory :google_book do
    googlebooksapi_id { 'wlNHDwAAQBAJ' }
    authors do
      [
        'Tomoaki Ota',
        'Shota Terashita',
        'Ryo Tezuka',
        'Ayumi Munezo',
        'Recruit Technologies Co., Ltd.'
      ]
    end
    image { 'http://books.google.com/books/content?id=wlNHDwAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&imgtk=AFLRE70j5lrdzOYN-iUu8w-G_JJKpEhnpUGAgqyZd7rj4jHu59NcAU48eQ75T4fkdyyZD6dMlwjjw0sAdQSKY_HiEdNBMMeyDn4DUmOcY-oLHFRAnxPXocc_T_PA7NYdSlZdwKckhCMy&source=gbs_api' }
    published_at { '2018-01-24' }
    title { 'Verwendung von Ruby on Rails 5 Praktische Methode zur Entwicklung von Rails-Anwendungen, die von Außendiensttechnikern gelehrt wird' }
  end
end

Vor-Ort-Schienen. Als nächstes folgt der Hauptteil des Modelltests.

app/models/google_book_spec.rb


require 'rails_helper'

RSpec.describe GoogleBook, type: :model do
  it 'Haben Sie eine gültige Fabrik' do
    google_book = build(:google_book)
    expect(google_book).to be_valid
  end

  it 'Ungültig, wenn die Google Books-API-ID nicht vorhanden ist' do
    google_book = build(:google_book, googlebooksapi_id: nil)
    google_book.valid?
    expect(google_book.errors.messages[:googlebooksapi_id]).to include('Bitte eingeben')
  end

  it 'Ungültig, wenn der Titel nicht vorhanden ist' do
    google_book = build(:google_book, title: nil)
    google_book.valid?
    expect(google_book.errors.messages[:title]).to include('Bitte eingeben')
  end

  it 'Die gewünschte Instanz aus der ID der Google Books-API generieren können' do
    googlebooksapi_id = 'YEfUBgAAQBAJ'
    google_book = GoogleBook.new_from_id(googlebooksapi_id)
    expect(google_book.title).to eq '2D-Spielprogrammierung beginnend mit SpriteKit Swift-Unterstützung'
    expect(google_book.googlebooksapi_id).to eq googlebooksapi_id
    expect(google_book.authors).to eq %w[Yoshitaka Yamashita Tomotsune Murata Tomoai Hara Hidehiko Kondo]
    expect(google_book.author).to eq 'Yoshitaka Yamashita'
  end

  it 'Gibt mehrere Suchergebnisse aus den entsprechenden Schlüsselwörtern zurück und der Titel enthält die Schlüsselwörter' do
    keyword = 'Ruby'
    keyword_count = 0
    google_books = GoogleBook.search(keyword)
    expect(google_books.size).to be >= 5 #Kann 5 oder mehr Suchergebnisse zurückgeben
    google_books.each do |google_book|
      if google_book.title.include?(keyword)
        keyword_count += 1
      end
    end
    expect(keyword_count).to be >= 5 #Kann 5 oder mehr Titel einschließlich des Schlüsselworts Ruby zurückgeben
  end

  it 'Geben Sie keine Suchergebnisse von unangemessenen Keywords zurück' do
    keyword = 'bbvjnaovnaov' #geeignet
    google_books = GoogleBook.search(keyword)
    expect(google_books.size).to be 0
  end

  describe 'Beim Speichern' do
    context 'Wenn Sie nur unangemessene Informationen haben' do
      let(:google_book) { build(:google_book, googlebooksapi_id: nil) }
      it 'Fehler beim Speichern' do
        expect { google_book.save }.to change { Book.count }.by(0).and change { Author.count }.by(0)
      end
      it 'Falsche Rückgabe' do
        expect(google_book.save).not_to be_truthy
      end
    end

    context 'Wenn Sie die richtigen Informationen haben' do
      let(:google_book) { build(:google_book, authors: [
                                  'Tomoaki Ota',
                                  'Shota Terashita',
                                  'Ryo Tezuka',
                                  'Ayumi Munezo',
                                  'Recruit Technologies Co., Ltd.'
                                ])
      }
      it 'Was kann gespeichert werden' do
        expect { google_book.save }.to change { Book.count }.by(1).and change { Author.count }.by(5)
      end
      it 'Rückgabe true' do
        expect(google_book.save).to be_truthy
      end
    end

    context 'Auch wenn Sie nicht nur die Informationen des Autors haben' do
      let(:google_book) { build(:google_book, authors: nil) }
      it 'Was kann gespeichert werden' do
        expect { google_book.save }.to change { Book.count }.by(1).and change { Author.count }.by(0)
      end
      it 'Rückgabe true' do
        expect(google_book.save).to be_truthy
      end
    end
  end
end

Ich habe gerade die Validierung und jede Methode getestet, daher denke ich, dass es nicht viel Erklärung braucht.

Fordern Sie bei der Registrierung eines Buches Spezifikationen an

spec/requests/books_spec.rb


require 'rails_helper'

RSpec.describe 'Books', type: :request do
  it 'In der Lage sein, ein Buch zu registrieren, das die ID der entsprechenden Google Books-API ist' do
    expect {
      post '/books', params: { googlebooksapi_id: 'xPbRxgEACAAJ' }
    }.to change { Book.count }.by(1)
    expect(response).to redirect_to book_path(Book.last.id)
  end

  it 'Fehler beim Registrieren eines bereits registrierten Buches und beim Übergang zum Detailbildschirm.' do
    same_google_books_api_id = 'xPbRxgEACAAJ'
    create(:book, googlebooksapi_id: same_google_books_api_id)
    expect {
      post '/books', params: { googlebooksapi_id: same_google_books_api_id }
    }.to change { Book.count }.by(0)
    expect(response).to redirect_to book_path(Book.find_by(googlebooksapi_id: same_google_books_api_id))
  end
end

Der entsprechende Controller ist der von "Resource Registration Controller Version 3 (abgeschlossen)". ~~ Der Test ist leicht und leicht zu erklären ~~

Das ist es. Ich würde es gerne verbessern, daher wäre ich Ihnen dankbar, wenn Sie auf Fehler oder Bereiche hinweisen könnten, die verbessert werden müssen.

Recommended Posts

Erstellen Sie ein Modell zum Speichern von Informationen aus der Google Books-API für eine intuitive Handhabung und Prüfung
Erstellen Sie eine saubere Datenbank zum Testen mit FastAPI und führen Sie Unittest of API mit pytest aus
Erstellen Sie eine REST-API mit dem in Lobe und TensorFlow Serving erlernten Modell.
Erstellen Sie mit RDKit einen Befehl zum Suchen nach ähnlichen Verbindungen aus der Zieldatenbank und überprüfen Sie die Verarbeitungszeit
Erstellen Sie eine Tweet-Heatmap mit der Google Maps-API
So veröffentlichen Sie ein Ticket über die Shogun-API
Erhalten Sie Daten von Poloniex, einem virtuellen Geldwechsel, über die API und verwenden Sie Deep Learning, um den Preis des nächsten Tages vorherzusagen.
Erstellen Sie mit Google Text To Speak eine Audiodatei mit der Text-to-Speech-Funktion und überprüfen Sie den Text 3 Minuten lang als Leitfaden für das Sprechen.
Erstellen Sie ein Skript für Ihre Pepper-Fertigkeit in einer Tabelle und laden Sie SayText direkt aus dem Skript
Analysieren Sie die Researchmap-API mit Python und erstellen Sie automatisch eine Word-Datei für die Leistungsliste
Senden Sie mithilfe von Google Cloud Messaging für Chrome eine Nachricht vom Server an die Chrome-Erweiterung
Ich habe versucht, verschiedene Informationen von der Codeforces-API abzurufen
Ich möchte vorerst eine Docker-Datei erstellen.
Ich möchte Informationen von fstab am ssh-Verbindungsziel abrufen und den Befehl ausführen
[Kartenanzeige] Zeigen Sie eine Karte anhand der vom Benutzer registrierten Adresse mit der JavaScript-API und der Geokodierungs-API von Google Maps an!
Erstellen Sie mit turicreate eine API, die Daten aus einem Modell zurückgibt
Erstellen Sie mit der AWS-API einen Alias für Route53 zu CloudFront
So erhalten Sie mithilfe der Mastodon-API Follower und Follower von Python
Erstellen Sie eine REST-API, um dynamodb mit dem Django REST Framework zu betreiben
[Rails] google maps api So posten und anzeigen Sie einschließlich Karteninformationen
Erstellen Sie mit Python einen Entscheidungsbaum von 0 und verstehen Sie ihn (5. Information Entropy)
Ich möchte eine API erstellen, die ein Modell mit einer rekursiven Beziehung im Django REST Framework zurückgibt
So speichern Sie die Feature-Point-Informationen des Bildes in einer Datei und verwenden sie zum Abgleichen
Ich habe mir eine Möglichkeit ausgedacht, ein 3D-Modell aus einem Foto zu erstellen. Teil 02 Laden von Bildern und Zeichnen von Scheitelpunkten
Erstellen Sie einen Bot, um Corona-Virus-Informationen zu retweeten
Erstellen Sie ein Modell für Ihren Django-Zeitplan
So erstellen Sie ein Repository aus Medien
[LINE Messaging API] Ich möchte eine Nachricht vom Programm an alle LINE senden
Verwenden Sie den Befehl [shell], um eine beliebige Datei zu komprimieren, um eine Datei zu erstellen und die Originaldatei zu löschen.
Verwendung von OAuth und API für Dienstkonten mit Google API Client für Python
Anweisungen zum Verbinden von Google Colab mit der lokalen Laufzeit in einer Windows-Umgebung
Erstellen Sie einen Filter, um ein Zugriffstoken mit der Graph-API (Flask) zu erhalten.
Ich habe versucht, ein Modell mit dem Beispiel von Amazon SageMaker Autopilot zu erstellen