[RUBY] [Rails] Search without distinction between hiragana, katakana, and kanji using the search form (accuracy is not 100%)

I implemented a search form in the app I am making as a PF. However, if you search with [rails search form], you will find many partial matches and exact matches. I wondered if I could somehow search for the kanji part with hiragana or katakana.

The flow is that when you save the title of the video, you convert the title to romaji and save it in a dedicated column, and when you search, you convert the search word to romaji and refer to it as a dedicated column. At first, I thought about converting all the titles when searching, but I thought that it would take time if the number of videos increased, so I chose the above method.

Since I am a beginner, I think that there is a part that I do not need to do such redundant things, but I will write it with the meaning of a memorandum, so please give it a big deal.

Referenced site

-Hiragana-Katakana-Kanji-I made a gem to convert Romaji -Memo when you want to distinguish whether the content or input information on the Web is English or Japanese -Let's master how to use Ruby regular expressions! match / gsub

Make a search form

The search form itself has various articles, so I think it's easy to create. In my case, it is a video posting site. In the search, create a search form that the search word matches the title of the video.

/application.html.erb


      <div id="search-box">
        <%= form_tag(search_path, :method => 'get') do %>
          <div class="input-tag">
            <%= text_field_tag :search, '', placeholder: 'Search', value: params[:title] %>
          </div>
          <div class="submit tag">
            <%= button_tag type: 'submit', class: 'btn btn-default' do %>
              <i class="fas fa-search"></i>
            <% end %>
          </div>
        <% end %>
      </div>

Skip the routing to the search action of the videos controller.

routes.rb


  #Search function
  get "search" => "videos#search"

I will add to the controller

Introduce gem. This time, I used a gem called miyabi. It is a gem that can be converted to Hiragana-Katakana-Romaji and judged. Method used this time

.to_roman   #Convert strings to romaji
.to_kanhira #Convert character strings containing kanji to hiragana
.is_hira?   #Judgment whether the character string is hiragana
.is_kana?   #Determine if the character string is katakana

After introducing gem, we will write create and search of the controller. For the model called Video user_id title introduction There is a column called conversion_title that saves the title converted to romaji.

schema.rb


  create_table "videos", force: :cascade do |t|
    t.integer "user_id"
    t.string "title"
    t.text "introduction"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "conversion_title"
  end

I'm creating a videos.controller create, but I'm having trouble.

With gem'miyabi', you can [Convert a character string that contains Kanji], but you cannot determine [Whether Kanji is included in the character string].

Determines whether ruby's regular expression contains kanji. This time I want to check if the kanji is included in the title, so let's pinpoint only the kanji.

@video.title.match(/[one-Storm]/)

Now you can determine if it contains kanji.

Save the video posted by create.

/videos_controller.rb


  def create
    @video = Video.new(video_params)
    @video.user_id = current_user.id
    if @video.title.match(/[one-Storm]/)
      @video.conversion_title = @video.title.to_kanhira.to_roman
    elsif @video.title.is_hira? || @video.title.is_kana?
      @video.conversion_title = @video.title.to_roman
    else
      @video.conversion_title = @video.title
    end
    if @video.save
      redirect_to video_path(@video)
    else
      render :new
    end
  end

  private

  def video_params
    params.require(:video).permit(:title, :introduction, :video)
  end

From top to bottom, first determine if the title contains kanji. If it is included, convert the title to Hiragana and then convert it to Romaji and save it.

If it does not contain kanji and is all hiragana or katakana, it will be converted to romaji and saved.

If neither is true, we will assume that it is posted in romaji and save it as is.

I will write the search action in the same way.

/videos_controller.rb


  def search
    word = params[:search]
    unless word.blank?
      if word.match(/[one-Storm]/)
        conversion_word = word.to_kanhira.to_roman
      elsif word.is_hira? || word.is_kana?
        conversion_word = word.to_roman
      else
        conversion_word = word
      end
    end
    @search_video = Video.search(conversion_word)
  end

The word searched in the form is assigned to word, and if word is included, it is converted to romaji. Similar to create, the conversion that meets the conditions is performed in order from the top. If the search word is searched without anything, all videos are returned.

The view of the search results looks like this.

/videos/search.html.erb


<h2>search results</h2>

      <% unless @search_video.blank? %>
        <div class="row">
        <% @search_video.each do |video| %>
        
        =====abridgement=====    
        
        <% end %>
        </div>
      <% else %>
        <p>No results</p>
      <% end %>
  </div>

If there is no match for the searched word, that fact is displayed. That's all there is to it.

Complete!

I will actually try it.

スクリーンショット 2020-09-28 13.30.22.png

Enter "sea turtle" in hiragana

スクリーンショット 2020-09-28 13.31.12.png

He returned a video with a conversion_title called "umigame". (There are many videos that have the title of sea turtle, but this is the video before adding conversion_title. Thank you.)

I will also search for romaji.

スクリーンショット 2020-09-28 14.38.18.png

スクリーンショット 2020-09-28 14.38.33.png

It was displayed.

Other

While testing, it may happen that the movement of the parameters changes when the browser back etc. is entered, or that all the videos are read. Maybe it's cash ... I think I have to study JS too.

Regarding kanji, although it is mentioned in the title, it does not seem to convert 100% perfectly. (In fact, the word "strongest" was converted to "saikiu") I think it can be used when you want to make a little search.

If there is a better way, please do.

Recommended Posts

[Rails] Search without distinction between hiragana, katakana, and kanji using the search form (accuracy is not 100%)
[Rails] What is the difference between redirect and render?
[Rails] What is the difference between bundle install and bundle update?
How to solve the problem when the value is not sent when the form is disabled in rails and sent
[Java] What is the difference between form, entity and dto? [Bean]
[Rails / ActiveRecord] About the difference between create and create!
What is the difference between SimpleDateFormat and DateTimeFormatter? ??