Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Rails where 메서드 사용법 완벽 가이드: 기본부터 심화까지 예제로 배우기

Rails에서는 모델을 통해 데이터베이스를 조회하여 데이터에 접근할 수 있습니다.

이때 ActiveRecord 메서드를 활용하는데, 대표적으로 where, find, find_by가 있습니다.

각 메서드의 반환 결과는 다음과 같습니다:

  • find_by: 단일 레코드 또는 nil 반환
  • where: ActiveRecord::Relation 객체 반환
  • find: 기본 키(보통 id)로 단일 레코드를 찾으며, 찾지 못하면 예외 발생

다시 말해, 레코드 하나(특정 사용자)를 찾을 때는 find_by를, 여러 레코드(사용자 목록)를 찾을 때는 where를 사용하면 됩니다.

하지만 where는 활용 방법이 매우 다양해서 초보자에게는 다소 혼란스러울 수 있습니다.

걱정 마세요! 이 글에서는 Rails 애플리케이션에서 where를 활용하는 여러 가지 방법을 하나씩 살펴보겠습니다.

기본 where 조건

where의 목적은 데이터베이스의 정보를 필터링하는 쿼리를 만들어, 원하는 행만 가져오는 것입니다.

예를 들어, title, author, category 컬럼을 가진 Book 모델이 있다고 가정해 보겠습니다.

특정 저자가 쓴 모든 책이나, 특정 카테고리에 분류된 모든 책을 찾고 싶을 수 있습니다.

쿼리 예시:

Book.where(category: "Ruby")

이 쿼리는 category가 "Ruby"인 모든 책을 반환합니다.

조건을 조합할 수도 있습니다.

이렇게 말이죠:

Book.where(category: "Ruby", author: "Jesus Castello")

categoryauthor가 모두 일치하는 책을 반환합니다.

또한 where는 스코프(scope)와 결합할 수도 있습니다.

# scope 정의
class Book
  scope :long_title, -> { where("LENGTH(title) > 20") }
end

# 컨트롤러 코드
@books = Book.long_title.where(category: "Ruby")

해시 형태(fruit: "apple")를 사용하면 특정 컬럼이 어떤 값과 같은지(equality) 확인할 수 있습니다.

하지만 동등성 검사가 아닌 조건이라면 문자열을 사용해야 합니다.

Rails where: 크다 / 작다 비교 조건

"크다", "작다" 같은 비교 조건을 확인하고 싶다면...

이렇게 작성하세요:

Book.where("LENGTH(title) > 20")

값을 동적으로 삽입(보간)해야 한다면...

이렇게 작성하세요:

Book.where("LENGTH(title) > ?", params[:min_length])

?는 "플레이스홀더(placeholder)"라고 불리며, SQL 인젝션(SQL injection) 공격을 방지하기 위한 보안 장치로 사용됩니다.

또 다른 방법으로 이름이 지정된 플레이스홀더(named placeholder)를 사용할 수도 있습니다.

예시:

Book.where("LENGTH(title) > :min", min: params[:min_length])

물음표 플레이스홀더보다는 덜 흔하게 사용되지만, 삽입해야 할 값이 많은 쿼리에서는 가독성 면에서 유용할 수 있습니다.

where.not과 where.or 조건 활용하기

이번에는 좀 더 복잡한 쿼리를 살펴보겠습니다.

특정 조건이 참이 아닌(NOT) 경우를 확인하려면 wherenot 메서드를 결합하면 됩니다.

예시:

Book.where.not(category: "Java")

또 다른 예시:

Book.where.not(title: nil)

이 쿼리는 titlenil이 아닌 Book을 찾습니다.

OR 조건은 어떻게 할까요?

whereor 메서드를 결합하면 두 개 이상의 조건 중 하나라도 일치하는 행을 얻을 수 있습니다.

동작 방식:

Book.where(category: "Programming").or(Book.where(category: "Ruby"))

두 개의 where 쿼리를 하나로 합친 것입니다.

직접 실행해 보세요!

Rails where 배열(IN) 조건 예제

지금까지 본 예제들은 모두 하나의 특정 값을 찾는 것이었습니다.

하지만 여러 값을 한 번에 찾을 수도 있습니다.

방법은? 바로 배열을 사용하는 것입니다!

예시:

Book.where(id: [1,2,3])

이 코드는 해당 ID들을 동시에 검색하는 "IN" 쿼리를 생성합니다.

SELECT "books".* FROM "books" WHERE "books"."id" IN (1, 2, 3)

이 쿼리는 Rails 로그에서 직접 확인할 수 있습니다.

Rails joins 연관 관계 조건

연관 관계(association)의 값을 기준으로 매칭하고 싶다면, 먼저 joins 메서드로 해당 연관 관계를 쿼리에 포함시켜야 합니다.

그다음 이렇게 작성할 수 있습니다:

Book.joins(:comments).where(comments: { id: 2 })

이 쿼리는 댓글(comment)을 가지고 있고, 그 댓글의 id2인 모든 책을 가져옵니다.

문자열 버전은 다음과 같습니다:

Book.joins(:comments).where("comments.id = 2")

여기서 comments는 테이블 이름, id는 컬럼 이름입니다.

where LIKE 조건으로 텍스트 검색 구현하기

검색 기능을 구현할 때는 부분 일치(partial match)를 허용하고 싶은 경우가 많습니다.

이럴 때 "LIKE" 쿼리를 사용하면 됩니다.

예시:

Book.where("title LIKE ?", "%" + params[:q] + "%")

이 쿼리는 파라미터(params[:q])로 전달된 검색어가 제목 어디에든 포함된 모든 책을 찾아줍니다.

검색 기능 구현에 매우 유용한 쿼리입니다!

퍼센트 기호(%)는 무엇일까요?

SQL에서 %는 와일드카드(wildcard) 문자로, 임의의 문자열을 의미합니다.

영상: where vs find_by 자세히 비교

아래 영상에서는 wherefind_by의 차이점을 더 자세히 설명하니, 함께 참고해 보세요.

요약

지금까지 Rails where 메서드를 사용해 ActiveRecord 모델을 조회하는 방법을 배웠습니다!

배운 내용:

  • 여러 조건을 조합해 데이터를 필터링하는 방법
  • 배열을 활용해 여러 행을 효율적으로 조회하는 방법
  • ornot 메서드와 결합해 더 복잡한 쿼리를 작성하는 방법

이제 직접 실습하며 익혀볼 차례입니다.

읽어주셔서 감사합니다 🙂