If you implement the search function using Rakuten API, you will get an error saying ** keyword is not valid ** when the search form is searched with blanks or one character. It is quick to count the number of characters in the corresponding action of the controller and make a conditional branch, or control the input form with Javascript, but then you can only limit the number of characters. I made an article about the process of setting validation like a normal model.
[Rakuten product search API] (http://webservice.rakuten.co.jp/api/ichibaitemsearch/)
[Please refer to the article I referred to (I'm sorry to leave it to others ...)] (https://freesworder.net/rakuten-api-rails/) The content of the above article is from creating a new application, but please refer to it according to your situation. I implemented it in the existing controller (searchs_controller.rb) of the existing application, but the flow was as follows. ① Rakuten app registration → Obtain required ID ② Add index action to searchs controller ③ Add routing (url does not have id) ④ Add Gem ⑤ Add rakuten.rb to the initializer folder (and make id an environment variable) ⑥ Edit controller ⑦ Create View (index.html.erb) Once you've done this, you'll partially edit it to set the validation.
Create search_form.rb directly under app/models. (The naming is free, so you can change it without any problem.)
models/search_form.rb
class SearchForm
  
  include ActiveModel::Model
   
  attr_accessor :keyword
  #Please change the following validation according to your needs(I haven't finished...)
  VALID_KEYWORD_REGEX = /\A(?:\p{Hiragana}|\p{Katakana}|[---]|[one-龠])+\z/
  validates :keyword, presence: true, length: { in: 2..20 }, format: { with: VALID_KEYWORD_REGEX}
end
** include ActiveModel :: Model ** is a very convenient module that allows you to create model classes that are not directly linked to the DB. [This is an article that I referred to] (https://naokirin.hatenablog.com/entry/2019/02/20/231317) ** attr_accessor ** seems to be used when you want to define the attributes of an object that can be read and written. In Rails, if you create a corresponding Model, you can handle table columns as attributes without explicitly defining attr_accessor, but this time it is a model that is not linked to DB, so I think that it is an image defined in class. I am thinking. (If you recognize it, please comment ...)
searchs_controller.rb
  def index
    #Determining if a search word exists(If there is no word, it feels like a view of only the search form is displayed)
    if params[:keyword]
      #SearchForm model keywords params[:keyword]Store
      items = SearchForm.new(keyword: params[:keyword])
      #Determining if you got stuck in validation(False)
      if items.valid?
        #.search()The keyword stored in items above is stored in items.I will give it by keyword.
        @items = RakutenWebService::Ichiba::Item.search(keyword: items.keyword)
      else
        #What to do if validation is applied
        flash[:danger] = "Message you want to display"
        redirect_to rakuten_search_path    #Arbitrary path
      end
    end
  end
ruby:searchs/index.html.erb
<div class="col-xs-10 col-xs-offset-1">
  <div class="rakuten-search-box">
    <%= form_with url: rakuten_search_path, method: :get, local: true do |f| %>
      <%= f.text_field 'keyword', placeholder: "Enter a search word...", class: "rakuten-search-form" %>
      <%= f.submit "Search", class: "rakuten-search-btn" %>
    <% end %>
  </div>
  <div class="alert">
    <%= flash[:danger] %>
  </div>
  <div class="rakuten-items">
    <% if @items.present? %>
      <% @items.each do |item| %>
        <%= link_to "#{item.url}" do %>
          <section class="item-detail">
            <%= image_tag item["mediumImageUrls"][0], class: "item-image" %>
            <p><%= item.name %></p>
            <p><%= item.price %>Circle</p>
          </section>
        <% end %>
      <% end %>
    <% else %>
      <p>There is no applicable product</p>
    <% end %>
  </div>
</div>
As an aside, I use Javascript to clear flash messages in 6 seconds. With the above, I think that validation was applied at the time of search. If you have an easier way or a practical implementation, please leave a comment.
Recommended Posts