Rails 6에서 고급 검색 양식 작성

소개


간단한 검색 폼은 좋지만, 고급 검색 옵션을 가진 폼은 많은 용례가 있을 수 있다.아마존의 검색표가 상품 이름만 받는다고 상상할 수 있습니까?...이것은 마치 악몽처럼 들린다.
나는 내 사용자에게 더 많은 선택을 제공하기를 원한다.더 많은 필터를 추가하면 사용자가 검색 결과의 범위를 좁히고 원하는 내용을 정확하게 찾을 수 있습니다.
Ransack 같은gem를 사용하여 검색 폼을 더 빨리 구축할 수 있지만, 학습과 성능을 위해 이 기능을 직접 구축할 것입니다.이 과정에서 Rails의 기본 다양성을 사용자 정의하는 방법도 학습하게 됩니다.마지막으로 우리는 이름, 유형, 지역에 따라 포켓몬을 검색할 수 있다.

저희가 잠수하기 전에.


나는 전체 과정에서 응용 프로그램을 테스트할 것을 건의한다.터미널에서 rails server을 실행하고 모든 기능이 실행된 후에 방문하여 프로그램이 예상대로 작동하는지 확인할 수 있습니다.

입문


먼저 새 Rails 응용 프로그램을 만듭니다.명령줄에서 다음 코드를 실행합니다.rails new PokemonDB그러면 응용 프로그램을 실행하는 데 필요한 전체 Rails 디렉토리 구조가 설정됩니다.비계를 구축하기 전에 우리는 포켓몬을 설치하여 적당한 다원화를 해야 한다.포켓몬은 이미 복수이기 때문에, 우리는 레일스가 그 뒤에's'를 추가하는 것을 원하지 않는다.
#pokemondb/config/initializers/inductions.rb형
ActiveSupport::Inflector.inflections do |inflect|
    inflect.uncountable "pokemon"
end
이제 우리는 우리의 첫 번째 모델, 포켓몬을 만들 수 있다.우리 모델에는 이름, 유형, 영역 등 세 개의 문자열이 있습니다.우리는 scaffold을 사용하여 이것을 생성할 것입니다. 이것은 우리가 필요로 하는 데이터베이스와 기본 MVC 설정을 생성할 것입니다.만약 당신이 추가적인 도전을 원한다면, 비계를 사용하지 않는 상황에서 자유롭게 건설할 수 있다.
참고 기본적으로 속성은 문자열로 설정됩니다.우리의 모든 속성은 문자열이기 때문에 데이터 형식을 지정할 필요가 없습니다.rails generate scaffold Pokemon name type region --force-plural비계를 설치한 후 Pokemon 클래스를 업데이트하여'type'을 Pokemon이 받아들일 수 있는 속성으로 만듭니다.Rails는 기본적으로 "type"을 유지합니다.
#pokemondb/app/models/pokemon.rb형
class Pokemon < ApplicationRecord
    self.inheritance_column = "not_sti"
end
업데이트 모드로 rails db:migrate을 따라가십시오.우리의 응용 프로그램은 중단된 마이그레이션에서 실행되지 않습니다.

라우팅 업데이트


루트 페이지의 동작을 변경하려면 routes을 업데이트해야 합니다. 정사각형으로 표시합니다.루트에 "pokemon#index"작업을 사용합니다.라우팅 파일 업데이트:
#pokemondb/config/routes.rb형
Rails.application.routes.draw do
  root 'pokemon#index'
  resources :pokemon
end
지금 우리의 루트 페이지는 이렇게 해야 한다.

창설 폼 테스트


"새 포켓몬"클릭세 개 또는 네 개의 포켓몬을 만들어서 폼을 테스트하고 색인 페이지를 검사합니다.이것은 또한 사용할 대상을 제공할 것이다.나는 이런 방법을 더욱 좋아한다. 왜냐하면 나는 나의 표를 테스트하고 씨앗을 구축할 수 있기 때문이다.

일단 포켓몬을 추가하면 색인 페이지에서 볼 수 있을 것이다.링크 표시, 편집 및 제거를 포함하여 생성된 순서대로 표시됩니다.다음 단계에서는 기본적인 검색 형식과 논리를 추가합니다.

이름별 검색


고급 검색을 구축하기 전에 기본적인 포켓몬 검색 폼을 구축하여 이름에 따라 검색합시다.우리는 잠시 후에 이것에 대해 상세하게 소개할 것이다.
이를 구축하려면 Pokemon 인덱스 파일의 form_with 태그를 사용합니다.이전 버전의 Rails를 사용하는 경우 form_tag은 약간의 차이만 있을 뿐 정상적으로 작동할 수 있습니다.다음 코드를 Pokemon 테이블 위의 색인 보기에 추가합니다.
#pokemondb/app/views/pokemon/index.html.erb 회사
<%= form_with(url: '/pokemon', method: 'get', local: true) do %>
  <%= text_field_tag(:search) %>
  <%= submit_tag("Search") %>
<% end %>
우리의 형식은 일종의 경로와 방법을 채택하고 있다.text_field_tag은 사용자가 검색 값을 입력할 수 있는 텍스트 상자를 표시하고, 제출 라벨은 우리가 사용하고 필터링할 수 있도록 정보를 보냅니다.만약 당신이 표를 복습하고 싶다면, 이것은 documentation입니다.

기본 검색 방법


수색 방법을 세울 때가 되었다.이것은 데이터베이스 논리이기 때문에 모델에 의해 처리될 것이다.이 방법은 주어진 명칭에 따라 포켓몬을 찾을 것이다.검색 매개 변수가 제공되지 않으면 모든 포켓몬을 표시합니다.당신의 포켓몬을 업데이트합니다.rb 파일은 다음과 같습니다.
#pokemondb/app/models/pokemon.rb형
class Pokemon < ApplicationRecord
    self.inheritance_column = "not_sti"

    def self.search(search)
        if search 
            where(["name LIKE ?","%#{search}%"])
        else
            all
        end
    end 
end
우리는 Pokemon 인덱스에서 그것을 호출해서 이 새로운 클래스 방법을 사용할 것이다.다음 코드는 우리가 이전에 구축한 검색 폼에서 검색 파라미터를 얻을 것입니다.
#pokemondb/app/controllers/pokemon_컨트롤러.rb형
def index
    @pokemon = Pokemon.search(params[:search])
end

기본 검색 폼은 이제 사용할 수 있습니다.나 Bulbasaur 찾았어!이 표를 더욱 유용하고 재미있게 할 때가 되었다.

모델 검색


다음은 유형과 지역에 따라 포켓몬을 검색하는 기능을 추가할 것입니다.이것은 좀 고급스러워서 검색을 처리하기 위한 단독 모델이 필요합니다.우리는 rails generate을 사용할 것이지만, 이번에는 모델에 사용할 것이다.이 모델에는 이름, 유형 및 영역이 있습니다.생성 후 rails db:migrate을 실행해야 합니다.rails generate model Search name type region

검색 컨트롤러


우리의 고급 검색 폼이 정상적으로 작동하기 위해서, 그것은 자신의 controller이 필요하다.컨트롤러 이름이 복수인지 확인하십시오.터미널에서 다음 명령을 실행하고 경로를 업데이트합니다.rails generate controller searches#pokemondb/config/routes.rb형
Rails.application.routes.draw do
  root 'pokemon#index'
  resources :pokemon
  resources :searches
end

컨트롤러 동작


컨트롤러는 세 개의 actions과 하나의'search_params'사유 방법이 있을 것이다.우리의 행동은 전시, 혁신과 창조이다.코드입니다.
참고: 이전 버전의 rails는 .uniq이 아니라 .distinct을 사용할 수 있습니다.어느 것이 틀릴지 시험해 보자.
#pokemondb/app/controllers/searches\u 컨트롤러.rb형
class SearchesController < ApplicationController
    def show
        @search = Search.find(params[:id])
    end 

    def new 
        @search = Search.new
        @types = Pokemon.distinct.pluck(:type)
        @regions = Pokemon.distinct.pluck(:region)
    end

    def create
        @search = Search.create(search_params)
        redirect_to @search
    end 

    private

    def search_params
        params.require(:search).permit(:name, :type, :region)
    end 
end

새 양식 만들기


우선 우리의 새로운 고급 검색 폼을 가리키는 링크를 만듭니다.이것은 포켓몬 인덱스 보기의 표준 검색 표에 직접 들어갈 수 있다.
#pokemondb/app/views/pokemon/index.html.erb 회사<%= link_to "Advanced Search", new_search_path %>이 링크는 어디에도 나타나지 않는다는 것을 알 수 있습니다.검색 폴더에 보기를 만들어야 합니다!뷰 new.html.erbshow.html.erb을 생성합니다.#pokemondb/app/views/searches 디렉터리에 있는지 확인하십시오.
지금 우리는 약간의 빈 보기가 있다.새로운 검색을 만들기 위해 코드를 추가할 때가 되었다.이것은 선택 메뉴와 제출 필드가 있는 폼이 될 것입니다.
#pokemondb/app/views/search/new.html.erb
<h1>Advanced Search</h1>

<%= form_with model: @search do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.label :type %>
    <%= f.select :type, options_for_select(@types), include_blank: true %><br>

    <%= f.label :region %>
    <%= f.select :region, options_for_select(@regions), include_blank: true %><br><br>

    <%= f.submit "Search" %>
<% end %>

<p><%= link_to "Back", '/pokemon' %></p>
우리의 고급 검색 보기는 매우 깨끗해 보일 것이다.모든 것이 예상대로 진행되는지 색인 페이지의 고급 검색 링크를 시도하십시오.Show 뷰로 이동합니다.
#pokemondb/app/views/search/show.html.erb 회사
<h1>Search Results</h1>
<p><%= link_to "Back", new_search_path %></p>

<% if @search.search_pokemon.empty? %>
    <p>No Pokemon were found.</p>
<% else %>
    <table>
        <thead>
            <tr>
                <th>Name</th>
                <th>Type</th>
                <th>Region</th>
                <th colspan="3"></th>
            </tr>
        </thead>

        <tbody>
            <% @search.search_pokemon.each do |pokemon| %>
            <tr>
                <td><%= pokemon.name %></td>
                <td><%= pokemon.type %></td>
                <td><%= pokemon.region %></td>
                <td><%= link_to 'Show', pokemon %></td>
                <td><%= link_to 'Edit', edit_pokemon_path(pokemon) %></td>
                <td><%= link_to 'Destroy', pokemon, method: :delete, data: { confirm: 'Are you sure?' } %></td>
            </tr>
            <% end %>
        </tbody>
</table>
<% end %>
이 시계는 비계가 생성한 시계와 거의 같다는 것을 알 수 있습니다.나는 그것을 쓰기로 결정했다. 왜냐하면 그것은 보기에 깨끗하고 읽기 쉽기 때문이다.

검색 모델 업데이트


우리의 포켓몬 모형처럼 모형을 검색하려면 포켓몬을 찾는 방법이 필요하다.이것은 실례 방법이 될 것입니다. 검색 실례에서 호출될 것입니다.우리는 .search_pokemon의 의견에서 이렇게 부른다.그것을 건설할 때가 되었다.이 모델은 "type"속성이 있기 때문에 받아들일 수 있는 속성으로 설정해야 한다는 것을 기억하십시오.우리는 검색 모델의 두 번째 줄에서 이 일을 완성했다.
#pokemondb/app/models/search.rb형
class Search < ApplicationRecord
    self.inheritance_column = "not_sti"

    def search_pokemon
        pokemon = Pokemon.all 

        pokemon = pokemon.where(['name LIKE ?', name]) if name.present?
        pokemon = pokemon.where(['type LIKE ?', type]) if type.present?
        pokemon = pokemon.where(['region LIKE ?', region]) if region.present?

        return pokemon
    end 
end

테스트 검색


모든 것이 정상적으로 일해야 한다!우리는 이름, 유형, 구역에 따라 포켓몬을 여과할 수 있어야 한다.우리가 추가한 각종 링크와 단추도 사용자가 사용하기에 매우 편리하다.이전 페이지로 돌아가서 우리의 포켓몬을 바꾸는 링크가 있어서 기쁩니다.
rails 서버를 실행하고 모든 작업을 보기 위해 접근합니다.

이 강좌를 읽어 주셔서 감사합니다.향후 Rails 프로젝트에 도움이 되었으면 합니다.

좋은 웹페이지 즐겨찾기