【Rails】ransack을 사용하지 않고 하나의 검색 막대에서 여러 테이블의 데이터를 검색합니다.

이 기사는 뛰어난 엔지니어의 첫걸음! AdventCalendar2020 9일차의 기사입니다.

만들고 싶은 것



아래 그림과 같이 하나의 검색 막대에서 여러 테이블의 데이터를 검색하는 기능을 구현합니다.
아래 그림에서는 Magic 테이블, Product 테이블, User 테이블의 3개의 테이블에 검색을 걸어, 각각의 테이블에서 검색 조건에 히트하는 데이터를 취득해, 탭으로 표시를 전환하고 있습니다.





할 일 요약



1. 검색 기능의 라우팅을 설정합니다.
2. 뷰에 검색 막대를 구현합니다.
3. 컨트롤러에 검색 기능을 구현한다.

1. 검색 기능의 라우팅 설정



검색 버튼을 클릭했을 때, 어떤 컨트롤러의 어느 액션을 호출하는지를 route.rb에 기재합니다.
아래 예제에서는 homes_controller.rb의 search 액션을 호출합니다.

route.rb

# 検索機能実施
get '/search' => 'homes#search', as: 'search'


2. 뷰에 검색 막대 구현



그런 다음 검색 양식을 준비합니다.
제 경우에는 헤더에 검색 양식을 표시하고 싶었으므로 _header.html.erb에 아래 코드를 구현했습니다.

_header.html.erb

<%= form_with url: search_path, method: :get, local: true do |f| %>

  <!-- 検索フォーム -->
  <%= f.text_field :content, :placeholder => "マジック動画タイトル、商品名、ユーザー名で検索" %>

  <!-- 検索ボタン -->
  <%= f.button :type => "submit" do %>
    <i class='fas fa-search'></i>
  <% end %>

<% end %>


해설



<%= form_with url: search_path, method: :get, local: true do |f| %>

form_with 도우미를 사용하여 검색 조건을 컨트롤러에 전달합니다.
여기에서는 URL에/search를 지정하고 get 메소드로 액세스한다는 내용을 쓰고 있습니다.

<!-- 検索フォーム -->
<%= f.text_field :content, :placeholder => "マジック動画タイトル、商品名、ユーザー名で検索" %>

f.text_field는 검색 양식의 검색 단어를 입력하는 input 요소를 가리킵니다.
입력한 검색어는 :content에 저장됩니다. (나중에 컨트롤러로 개봉합니다.)

<!-- 検索ボタン -->
<%= f.button :type => "submit" do %>
  <i class='fas fa-search'></i>
<% end %>

form_with 헬퍼에서는 submit 버튼을 클릭하면 지정된 라우팅 대상으로 천이하게 되어 있습니다.
여기에서는 그 submit 버튼을 돋보기 아이콘으로 하는 처리를 쓰고 있습니다.

3. 컨트롤러에 검색 기능 구현



컨트롤러는 form_with 헬퍼에서 보낸 검색어(:content)를 받고 이를 바탕으로 3개의 테이블 각각에서 검색을 걸고 있습니다.

homes_controller.rb

# 検索機能
def search
  # 検索ワード
  content = params['content']
  # 投稿検索結果
  @magics = partical_magic(content)
  # 商品検索結果
  @products = partical_product(content)
  # ユーザー検索
  @users = partical_user(content)
end

private

# 投稿検索
def partical_magic(content)
  Magic.where('title LIKE ?', "%#{content}%")
end

# 商品検索
def partical_product(content)
  Product.where('name LIKE ?', "%#{content}%")
end

# ユーザー検索
def partical_user(content)
  User.where('display_name LIKE ?', "%#{content}%")
end

해설



# 検索ワード
content = params['content']

form_with 헬퍼로부터 보내 온 파라미터:content의 내용, 즉 검색 워드를 content 변수에 격납하고 있습니다.

# 投稿検索結果
@magics = partical_magic(content)
# 商品検索結果
@products = partical_product(content)
# ユーザー検索
@users = partical_user(content)

검색 결과에 대한 인스턴스 변수를 3개 준비하고 각각 검색 결과를 저장합니다.
각각의 식의 우변에서는 검색을 실시하는 메소드에 방금 저장한 content 변수를 인수로서 건네주고 있습니다.

# 投稿検索
def partical_magic(content)
  Magic.where('title LIKE ?', "%#{content}%")
end

# 商品検索
def partical_product(content)
  Product.where('name LIKE ?', "%#{content}%")
end

# ユーザー検索
def partical_user(content)
  User.where('display_name LIKE ?', "%#{content}%")
end

각각의 테이블에 대해 검색을 실시해, 데이터를 돌려주는 메소드입니다.
모델명 .where('[검색 대상 열] LIKE ?', "%#{content}%")
라는 식으로 되어 있습니다.
위의 예는 부분 일치 검색입니다.

결론



검색 결과 화면도 올라가면 좋겠다고 생각했는데, 꽤 복잡해져서 이번에는 할애를 했어요...땀

좋은 웹페이지 즐겨찾기