ruby 2.5.8 rails 5.2.4 Bootstrap 3.4
Click on the title
Values are set in the form, and you can easily register books.
It is assumed that BooksController has been created.
First is the book search function. This time I will use the Google Book API to register books, so I will describe the search function in the new action.
books_controller
def new
@book = Book.new
#Book search API processing
if params[:keyword].present?
require 'net/http'
url = 'https://www.googleapis.com/books/v1/volumes?q='
request = url + params[:keyword]
enc_str = URI.encode(request)
uri = URI.parse(enc_str)
json = Net::HTTP.get(uri)
@bookjson = JSON.parse(json)
count = 5 #Number to display in search results
@books = Array.new(count).map{Array.new(4)}
count.times do |x|
@books[x][0] = @bookjson.dig("items", x, "volumeInfo", "title")
@books[x][1] = @bookjson.dig("items", x, "volumeInfo", "imageLinks", "thumbnail")
@books[x][2] = @bookjson.dig("items", x, "volumeInfo", "authors")
@books[x][2] = @books[x][2].join(',') if @books[x][2] #Separate multiple authors with commas
@books[x][3] = @bookjson.dig("items", x, "volumeInfo", "industryIdentifiers", 0, "identifier")
end
end
end
GoogleBook API does not need to be registered
If you give a search word to https://www.googleapis.com/books/v1/volumes?q=
, the search result will be returned in json format.
When searching with Rails, it looks like this ↓ https://www.googleapis.com/books/v1/volumes?q=rails
The acquired json is converted to a hash using JSON.parce, and the desired value is extracted from it.
You can also get it with @bookjson ["items "] [x] [volumeInfo] [title]
, but if some data does not exist, NoMethodError will occur. Exception handling can be done by conditional branching, but it is a little redundant.
So I'm digging a hash using the dig method. If there is no value corresponding to the key, it will return nil, so it's safe.
Create a search window and search result field in the view.
ruby:new.html.erb
<h1>New registration of books</h1>
<%= form_tag('/booksearch', method: :get) do %>
<div class="input-group">
<%= search_field_tag "keyword", params[:keyword], class: "form-control", placeholder: "Keyword search" %>
<span class="input-group-btn">
<%= submit_tag "Search", class: "btn btn-primary" %>
</span>
</div>
<% end %>
<h2>search results</h2>
<% if @books.present? %>
<% @books.each do |book| %>
<img src="<%= book[1] %>" width="40" vspace="2">
<%= book[0] %> |
<%= book[2] %> |
<%= book[3] %> <br>
<% end %>
<% end %>
Let's also write the routing for the search window
routes.rb
resources :books
get '/booksearch', to: 'books#new'
This completes the search function.
Next, prepare the book registration form.
ruby:new.html.erb
<%= form_with scope: :book, url: books_path, local: true do |form| %>
<%= render 'shared/error_messages' %>
<%= form.label :title %>
<%= form.text_field :title, class: 'form-control', value: "#{@title}" %>
<%= form.label :author %>
<%= form.text_field :author, class: 'form-control', value: "#{@author}" %>
<%= form.label :code %>
<%= form.text_field :code, class: 'form-control', value: "#{@code}" %>
<%= form.hidden_field :img, class: 'form-control', value: "#{@img}" %
<%= form.submit "Save Book", class: "btn btn-primary" %>
<% end %>
The point is that it is value:" # {@ title} "
, and it receives the value.
The URL of the image thumbnail is received by hidden_field
because it does not need to be modified.
Create a mechanism to submit values to the form.
ruby:new.html.erb
...
<img src="<%= book[1] %>" width="40" vspace="2">
<%= link_to book[0], controller: "books", action: "new", title: book[0], code: book[3], author: book[2], img: book[1] %>
<%= book[2] %> |
...
Paste the link with the query on the book [0](* book title) displayed in the search results earlier. This will send the value to the controller.
books_controller
def new
...
@title = params[:title] if params[:title].present?
@code = params[:code] if params[:code].present?
@author = params[:author] if params[:author].present?
@img = params[:img] if params[:img].present?
end
Added the process of receiving query parameters to the new action. Store it in an instance variable for the view (form).
This is complete. If you have any questions, please leave a comment.
Recommended Posts