The Codest
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 산업 분야
    • 핀테크 및 뱅킹
    • E-commerce
    • 애드테크
    • 헬스 테크
    • 제조
    • 물류
    • 자동차
    • IOT
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
뒤로 화살표 뒤로 가기
2022-02-23
소프트웨어 개발

Rails API의 간단한 필터

The Codest

크지슈토프 부제비츠

시니어 Software Engineer

데이터를 필터링하기 위해 레일즈 컨트롤러에서 변하는 인스턴스 변수를 볼 때마다 화가 나시나요? 이 글은 여러분을 위한 글입니다.

필터

이전에 본 적이 있을 것입니다:

# 앱/컨트롤러/api/v1/things_controller.rb

모듈 API
  모듈 V1
    class ThingsController < BaseController
      def index
        @things = Thing.all
        things = @things.where(size: params[:size]) if params[:size]
        things = @things.where('name ILIKE ?', "%#{params[:name_contains]}%") if params[:name_contains]

        json을 렌더링합니다: @things
      end
    end
  end
end

왜 나쁜가요? 코드? 컨트롤러를 뚱뚱하게 만들기 때문입니다.
IMHO 우리는 컨트롤러에서 최대한 많은 로직을 추출하고 목적과 관련된 로직을 사용해야 합니다.
유틸리티 또는 서비스. 이 경우 다음과 같은 일반 필터를 구현합니다.
를 사용하여 여러 컨트롤러에서 사용할 수 있습니다.

하지만 잠시만요, 먼저 현재 코드를 분석해 보겠습니다. 나쁘지만 그래도 작동합니다.
초기 범위(Thing.all)를 통과한 경우 이를 제한하고 있습니다.
관련 매개변수를 추가합니다. 각 필터에 대해 매개변수가 전달되었는지, 전달되었다면 실제로 확인합니다,
필터를 적용합니다. 두 번째는 아이바를 사용할 필요 없이 다음을 사용할 수 있다는 것입니다.
평범한 오래된 로컬 변수입니다.

좋아요, 그럼. 서비스 객체를 사용하여 초기 범위를 변경할 수 없나요?
실행은 다음과 같이 보일 수 있습니다:

# 앱/컨트롤러/api/v1/things_controller.rb

모듈 API
  모듈 V1
    class ThingsController < BaseController
      def index
        scope = Thing.all
        things = Things::IndexFilter.new.call(scope, params)

        렌더 제이슨: things
      end
    end
  end
end

지금은 훨씬 좋아 보이지만 물론 아직 필터를 구현해야 합니다.
호출의 서명은 모든 리소스에 대해 동일하므로 다음을 사용할 수 있습니다.
이 작업에 대한 일반 클래스를 지정합니다.

# app/services/generic/index_filter.rb

모듈 제네릭
  클래스 IndexFilter
    EMPTY_HASH = {}.freeze

    def self.filters
      EMPTY_HASH
    end

    def call(scope, params)
      apply_filters!(self.class.filters.keys, scope, params)
    end

    private

    def apply_filters!(filter_keys, scope, params)
      filter_keys.inject(scope.dup) do |current_scope, filter_key|
        apply_filter!(filter_key, current_scope, params)
      end
    end

    def apply_filter!(filter_key, scope, params)
      filter = fetch_filter(filter_key)
      apply_filter?(filter, params) 아니면 scope 반환

      filter[:apply].call(scope, params)
    end

    def apply_filter?(filter, params)
      filter[:apply?].call(params)
    end

    def fetch_filter(filter_key)
      self.class.filters.fetch(filter_key) { raise ArgumentError, '알 수 없는 필터' }
    end
  end
end

복잡해 보이시나요? 그렇지 않습니다. 모든 마법은 다음에서 일어납니다. #apply_filters!.
초기 범위의 복제본을 가져와 각 필터를 적용합니다.

범위를 적용한다는 것은 초기 범위의 복제본을 변경한다는 의미입니다.
그리고 필터가 해시로 구현될 것으로 예상됩니다. self.filters 메서드
의 하위 클래스를 만들 수 있습니다. 해봅시다.

# app/services/things/index_filter.rb

Things 모듈
  클래스 인덱스필터 (params) {
          params[:size].is_a?(String)
        },
        apply: ->(scope, params) {
          scope.where(size: params[:size])
        }
      }.freeze,
      name_contains_filter: {
        apply?: ->(params) {
          params[:name_contains].is_a?(문자열)
        },
        apply: ->(scope, params) {
          scope.where('name ILIKE ?', "%#{params[:name_contains]}%")
        }
      }.freeze
    }.freeze

    def self.filters
      FILTERS
    end
  end
end

여기까지입니다! 더 많은 코드를 작성했지만 간단한 필터는 동일하게 보입니다.
모든 리소스에 대한 방법. 담당 코드에서 컨트롤러를 정리했습니다.
필터링을 수행하고 이를 위해 다음과 같은 '특수' 클래스를 제공합니다.
명확한 관습.

루비 개발자 혜택

자세히 읽어보세요:

루비 소프트웨어 개발의 장단점

철도 및 기타 운송 수단

TMUX, Vim, Fzf + Ripgrep을 사용한 레일 개발

관련 문서

상승하는 화살표와 비용 효율성 또는 절감을 상징하는 금화가 있는 하락하는 막대 차트의 추상적인 그림. 밝은 회색 바탕에 "In Code We Trust"라는 슬로건과 함께 왼쪽 상단에 The Codest 로고가 표시됩니다.
소프트웨어 개발

제품 품질 저하 없이 개발팀을 확장하는 방법

개발팀을 확장하고 계신가요? 제품 품질을 저하시키지 않고 성장하는 방법을 알아보세요. 이 가이드에서는 확장할 시기의 징후, 팀 구조, 채용, 리더십 및 도구와 더불어 The Codest가 어떻게...

최신
소프트웨어 개발

미래 지향적인 웹 앱 구축: The Codest의 전문가 팀이 제공하는 인사이트

The Codest가 최첨단 기술로 확장 가능한 대화형 웹 애플리케이션을 제작하고 모든 플랫폼에서 원활한 사용자 경험을 제공하는 데 탁월한 성능을 발휘하는 방법을 알아보세요. Adobe의 전문성이 어떻게 디지털 혁신과 비즈니스를 촉진하는지 알아보세요...

최신
소프트웨어 개발

라트비아에 본사를 둔 10대 소프트웨어 개발 기업

최신 기사에서 라트비아 최고의 소프트웨어 개발 기업과 그들의 혁신적인 솔루션에 대해 알아보세요. 이러한 기술 리더들이 어떻게 귀사의 비즈니스를 향상시키는 데 도움을 줄 수 있는지 알아보세요.

thecodest
엔터프라이즈 및 스케일업 솔루션

Java 소프트웨어 개발 필수 사항: 성공적인 아웃소싱을 위한 가이드

The Codest로 효율성을 높이고 전문 지식을 활용하며 프로젝트 성공을 이끌 수 있는 성공적인 outsourcing Java 소프트웨어 개발에 대한 이 필수 가이드를 살펴보세요.

thecodest
소프트웨어 개발

폴란드 아웃소싱을 위한 최고의 가이드

폴란드에서 outsourcing가 급증한 것은 경제, 교육, 기술 발전으로 인한 IT 성장과 비즈니스 친화적인 환경이 조성된 덕분입니다.

더코데스트

지식창고를 구독하고 IT 분야의 전문 지식을 최신 상태로 유지하세요.

    회사 소개

    The Codest - 폴란드에 기술 허브를 둔 국제 소프트웨어 개발 회사입니다.

    영국 - 본사

    • 사무실 303B, 182-184 하이 스트리트 노스 E6 2JA
      영국 런던

    폴란드 - 현지 기술 허브

    • 파브리츠나 오피스 파크, 알레야
      포코주 18, 31-564 크라쿠프
    • 뇌 대사관, 콘스트럭터스카
      11, 02-673 바르샤바, 폴란드

      The Codest

    • 홈
    • 회사 소개
    • 서비스
    • Case Studies
    • 방법 알아보기
    • 채용 정보
    • 사전

      서비스

    • IT 자문
    • 소프트웨어 개발
    • 백엔드 개발
    • 프론트엔드 개발
    • Staff Augmentation
    • 백엔드 개발자
    • 클라우드 엔지니어
    • 데이터 엔지니어
    • 기타
    • QA 엔지니어

      리소스

    • 외부 소프트웨어 개발 파트너와의 협력에 대한 사실과 오해
    • 미국에서 유럽으로: 미국 스타트업이 유럽으로 이전을 결정하는 이유
    • 테크 오프쇼어 개발 허브 비교: 테크 오프쇼어 유럽(폴란드), 아세안(필리핀), 유라시아(터키)
    • CTO와 CIO의 주요 과제는 무엇인가요?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • 웹사이트 이용 약관

    저작권 © 2025 by The Codest. 모든 권리 보유.

    ko_KRKorean
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek ko_KRKorean