window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(funktion () { var w = vindue if (w.LeadBooster) { console.warn('LeadBooster findes allerede') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Simple filtre i Rails API - The Codest
Codest
  • Om os
  • Serviceydelser
    • Udvikling af software
      • Frontend-udvikling
      • Backend-udvikling
    • Staff Augmentation
      • Frontend-udviklere
      • Backend-udviklere
      • Dataingeniører
      • Cloud-ingeniører
      • QA-ingeniører
      • Andet
    • Det rådgivende
      • Revision og rådgivning
  • Industrier
    • Fintech og bankvirksomhed
    • E-commerce
    • Adtech
    • Sundhedsteknologi
    • Produktion
    • Logistik
    • Biler
    • IOT
  • Værdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leder af levering
  • Vores team
  • Casestudier
  • Ved hvordan
    • Blog
    • Møder
    • Webinarer
    • Ressourcer
Karriere Tag kontakt til os
  • Om os
  • Serviceydelser
    • Udvikling af software
      • Frontend-udvikling
      • Backend-udvikling
    • Staff Augmentation
      • Frontend-udviklere
      • Backend-udviklere
      • Dataingeniører
      • Cloud-ingeniører
      • QA-ingeniører
      • Andet
    • Det rådgivende
      • Revision og rådgivning
  • Værdi for
    • ADMINISTRERENDE DIREKTØR
    • CTO
    • Leder af levering
  • Vores team
  • Casestudier
  • Ved hvordan
    • Blog
    • Møder
    • Webinarer
    • Ressourcer
Karriere Tag kontakt til os
Pil tilbage GÅ TILBAGE
2022-02-23
Udvikling af software

Simple filtre i Rails API

Codest

Krzysztof Buszewicz

Senior Software Engineer

Bliver du vred, hver gang du ser muterende instansvariabler i rails controller for at filtrere data? Så er denne artikel noget for dig.

Filtre

Du har sikkert set det før:

# app/controllers/api/v1/things_controller.rb

modul API
  modul V1
    klasse ThingsController < BaseController
      def index
        @things = Ting.alle
        @things = @things.where(size: params[:size]) if params[:size]
        @things = @things.where('name ILIKE ?', "%#{params[:name_contains]}%") if params[:name_contains]

        render json: @things
      slut
    slut
  slut
slut

Hvorfor mener jeg, at det er en dårlig Kode? Fordi det simpelthen gør vores controller fed.
IMHO bør vi udtrække så meget logik som muligt fra controllere og bruge en formålsrelateret
værktøjer eller tjenester. I dette tilfælde vil vi implementere et generisk filter, som vi vil kunne
at bruge på tværs af mange controllere.

Men vent, lad os først analysere den nuværende kode. Den kan være dårlig, men fungerer dog.
Vi har nogle indledende muligheder (Ting.alle) og begrænser den derefter, hvis brugeren har bestået
relateret parameter. For hvert filter tjekker vi faktisk, om parameteren blev sendt, og i så fald,
vi anvender et filter. Den anden ting er, at vi ikke behøver at bruge ivar, vi kan bruge
almindelige gamle lokale variabler.

Okay, så. Kan vi ikke bruge et serviceobjekt til at mutere det oprindelige scope?
Udførelsen kan se sådan ud:

# app/controllers/api/v1/things_controller.rb

modul API
  modul V1
    klasse ThingsController < BaseController
      def index
        scope = Ting.alle
        ting = Things::IndexFilter.new.call(scope, params)

        render json: ting
      end
    slut
  slut
slut

Det ser meget bedre ud nu, men vi mangler selvfølgelig at implementere filteret.
Bemærk, at kaldets signatur vil være den samme for alle ressourcer, så vi kan have
en generisk klasse til denne opgave.

# app/services/generic/index_filter.rb

modul Generisk
  klasse IndexFilter
    EMPTY_HASH = {}.freeze

    def self.filters
      EMPTY_HASH
    end

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

    privat

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

    def apply_filter!(filter_key, scope, params)
      filter = hent_filter(filter_key)
      return scope unless apply_filter?(filter, params)

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

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

    def fetch_filter(filter_key)
      self.class.filters.fetch(filter_key) { raise ArgumentError, 'ukendt filter' }
    end
  end
slut

Virker det kompliceret? Egentlig ikke - al magien sker i #apply_filters!.
Vi tager duplikatet af det oprindelige scope og anvender hvert filter på det.

Når vi anvender scopet, betyder det, at vi muterer duplikatet af vores oprindelige scope.
Og vi forventer, at filtre implementeres som en hash i self.filters metode
af en børneklasse. Lad os gøre det.

# app/services/things/index_filter.rb

modul Ting
  class IndexFilter (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?(String)
        },
        apply: ->(scope, params) {
          scope.where('name ILIKE ?', "%#{params[:name_contains]}%")
        }
      }.freeze
    }.freeze

    def self.filters
      FILTERS
    end
  end
slut

Så er det nok! Vi har skrevet mere kode, men de enkle filtre vil se ud på samme måde
måde for alle ressourcerne. Vi har renset controlleren fra den ansvarlige kode
af filtrering og leverede en 'specialiseret' klasse til dette formål, der følger meget
klar konvention.

Ruby-udvikler-tilbud

Læs mere om det:

Fordele og ulemper ved Ruby-softwareudvikling

Skinner og andre transportmidler

Rails-udvikling med TMUX, Vim, Fzf + Ripgrep

Relaterede artikler

Udvikling af software

Byg fremtidssikrede webapps: Indsigt fra The Codest's ekspertteam

Oplev, hvordan The Codest udmærker sig ved at skabe skalerbare, interaktive webapplikationer med banebrydende teknologier, der leverer sømløse brugeroplevelser på tværs af alle platforme. Lær, hvordan vores ekspertise driver digital transformation og...

DENKODEST
Udvikling af software

Top 10 Letlands-baserede softwareudviklingsvirksomheder

Læs om Letlands bedste softwareudviklingsvirksomheder og deres innovative løsninger i vores seneste artikel. Find ud af, hvordan disse teknologiledere kan hjælpe med at løfte din virksomhed.

thecodest
Løsninger til virksomheder og scaleups

Grundlæggende om Java-softwareudvikling: En guide til succesfuld outsourcing

Udforsk denne vigtige guide til vellykket outsourcing af Java-softwareudvikling for at forbedre effektiviteten, få adgang til ekspertise og skabe projektsucces med The Codest.

thecodest
Udvikling af software

Den ultimative guide til outsourcing i Polen

Den voldsomme stigning i outsourcing i Polen er drevet af økonomiske, uddannelsesmæssige og teknologiske fremskridt, der fremmer it-vækst og et erhvervsvenligt klima.

TheCodest
Løsninger til virksomheder og scaleups

Den komplette guide til IT-revisionsværktøjer og -teknikker

IT-revisioner sikrer sikre, effektive og kompatible systemer. Lær mere om deres betydning ved at læse hele artiklen.

Codest
Jakub Jakubowicz CTO og medstifter

Tilmeld dig vores vidensbase, og hold dig opdateret om ekspertisen fra it-sektoren.

    Om os

    The Codest - International softwareudviklingsvirksomhed med tech-hubs i Polen.

    Storbritannien - Hovedkvarter

    • Kontor 303B, 182-184 High Street North E6 2JA
      London, England

    Polen - Lokale teknologiske knudepunkter

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Hjerneambassaden, Konstruktorska
      11, 02-673 Warszawa, Polen

      Codest

    • Hjem
    • Om os
    • Serviceydelser
    • Casestudier
    • Ved hvordan
    • Karriere
    • Ordbog

      Serviceydelser

    • Det rådgivende
    • Udvikling af software
    • Backend-udvikling
    • Frontend-udvikling
    • Staff Augmentation
    • Backend-udviklere
    • Cloud-ingeniører
    • Dataingeniører
    • Andet
    • QA-ingeniører

      Ressourcer

    • Fakta og myter om at samarbejde med en ekstern softwareudviklingspartner
    • Fra USA til Europa: Hvorfor beslutter amerikanske startups sig for at flytte til Europa?
    • Sammenligning af Tech Offshore-udviklingsknudepunkter: Tech Offshore Europa (Polen), ASEAN (Filippinerne), Eurasien (Tyrkiet)
    • Hvad er de største udfordringer for CTO'er og CIO'er?
    • Codest
    • Codest
    • Codest
    • Privacy policy
    • Vilkår for brug af hjemmesiden

    Copyright © 2025 af The Codest. Alle rettigheder forbeholdes.

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