window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster가 이미 존재합니다') } else { w.LeadBooster = { q: [], on: 함수 (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 함수 (n) { this.q.push({ t: 't', n: n }) }, } } })() Rails API의 간단한 필터 - The Codest
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을 사용한 레일 개발

관련 문서

소프트웨어 개발

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

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

최신
소프트웨어 개발

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

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

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

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

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

thecodest
소프트웨어 개발

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

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

더코데스트
엔터프라이즈 및 스케일업 솔루션

IT 감사 도구 및 기술에 대한 완벽한 가이드

IT 감사는 안전하고 효율적이며 규정을 준수하는 시스템을 보장합니다. 전체 기사를 읽고 그 중요성에 대해 자세히 알아보세요.

The Codest
야쿱 야쿠보비치 CTO & 공동 설립자

지식창고를 구독하고 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