Skip to content

Latest commit

 

History

History
34 lines (26 loc) · 1.4 KB

Scope.md

File metadata and controls

34 lines (26 loc) · 1.4 KB

Scope 혹은 Where

ActiveRecord::Relation#where는 다음 두 가지 방식으로 쓸 수 있다.

User.where(name: name)
User.where("name: ?", name)

# 좀 더 복잡하게
User.where(name: name).or(User.where(email: email))
User.where("name = ? OR email = ?", name, email)

둘 모두 parameterize 되는 안정적인 코드이고, 구문이 복잡해지는 경우 후자가 더 깔끔하게 보이지만, 전자를 선호하는 이유는 동일 컬럼을 가지고 있는 join이 일어나는 상황에서 PG::AmbiguousColumn 같은 오류를 막아주기 때문이다. 대부분의 인라인 상황에서는 별 차이가 없겠지만 어떤 쿼리가 이어질 지 모르는 scope를 구현하는 경우 특히 유용하다.

  scope :with_friend, ->(value) {
    self_join = -> { joins("left join users friends on user.friend_id = friends.id") }
    # ...
  }
  scope :name, ->(name) {
    where("name = ?", name) # with_friend와 함께 사용시 AmbiguousColumn 에러!
  }

부가적으로, 전자의 구문은 인자가 배열인 경우에도 코드를 수정할 필요 없이 알아서 잘 처리해준다. 보통은 단일 값이 들어올지 복수 값이 들어올지 명확하므로, 이 또한 scope 구현시 특히 유용하다.

value = "abc"
User.where(name: value) # where name = 'abc'

value = ["abc", "def"]
User.where(name: value) # where name in ('abc', 'def')