Rails 5 : ActiveRecord 또는 쿼리


답변:


228

체인에있는 기능 or과 함께 절 where에서 절 ActiveRecord쿼리에서 사용할 수 레일 (5) . 관련 토론 및 pull 요청을 참조하십시오 .

따라서 Rails 5 에서 다음 작업을 수행 할 수 있습니다 .

를 얻으려면 post함께 id1 또는 2 :

Post.where('id = 1').or(Post.where('id = 2'))

몇 가지 다른 예 :

(A && B) || 씨:

    Post.where(a).where(b).or(Post.where(c))

(A || B) && C :

    Post.where(a).or(Post.where(b)).where(c)

3
(A || B) && (C || D)를 어떻게 얻을 수 있습니까? Post.where (a) .or (Post.where (b)). where (c) .or (Post.where (d)) 시도했지만 다음과 같이 생성됩니다. (A || B) && C || D
Imran Ahmad

3
난 판단 @Imran는 것 Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))이 (c || d) && (a ||의 B)을 생성한다
engineersmnky

1
@Imran 이것은 나를 위해 작동하지 않는 것 같습니다 : 나는 얻습니다ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Suan

5
관계를 취하고 생성하는 .or에 해당하는 것은 .merge입니다. (A || B) && (C || D)는 Post.where (a) .or (Post.where (b)). merge (Post.where (c) .or (Post.where (d )))
Siim Liiser

2
@MathieuJ. ActiveRecord :: Relation # merge입니다. api.rubyonrails.org/classes/ActiveRecord/...
Siim Liiser

13

Rails 5가이 OR쿼리 를 사용할 때까지 기다릴 필요가 없습니다 . 우리는 rails 4.2.3. 여기에 백 포트가 있습니다 .

gem where-or에 대해 Eric-Guo 에게 감사합니다 . 이제이 gem을 사용하여이 기능을 추가 할 수 있습니다 .OR>= rails 4.2.3


6

(KM Rakibul Islam의 답변에 추가되었습니다.)

범위를 사용하면 코드가 더 예뻐질 수 있습니다 (눈에 따라 달라짐).

scope a,      -> { where(a) }
scope b,      -> { where(b) }

scope a_or_b, -> { a.or(b) }

5

나는 할 필요가 있었다 (A && B) || (C && D) || (E && F)

그러나 Rails 5.1.4의 현재 상태에서는 Arel 또는 체인으로 달성하기에는 너무 복잡합니다. 하지만 여전히 Rails를 사용하여 가능한 한 많은 쿼리를 생성하고 싶었습니다.

그래서 나는 작은 해킹을 만들었습니다.

내 모델에서 다음과 같은 개인 메서드를 만들었습니다 sql_where.

private
  def self.sql_where(*args)
    sql = self.unscoped.where(*args).to_sql
    match = sql.match(/WHERE\s(.*)$/)
    "(#{match[1]})"
  end

다음으로 내 스코프에서 OR를 보관할 배열을 만들었습니다.

scope :whatever, -> {
  ors = []

  ors << sql_where(A, B)
  ors << sql_where(C, D)
  ors << sql_where(E, F)

  # Now just combine the stumps:
  where(ors.join(' OR '))
}

예상되는 쿼리 결과를 생성합니다 SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))..

이제 잘못된 OR없이 이것을 다른 범위 등과 쉽게 결합 할 수 있습니다.

: 아름다움은 내 sql_where 정상 절 인수를 소요되고 sql_where(name: 'John', role: 'admin')생성합니다 (name = 'John' AND role = 'admin').


.merge&&와 동등하게 사용할 수 있고 괄호를 캡처하기 위해 적절한 트리를 구축 할 수 있다고 생각합니다 . 같은 뭔가 ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))의 범위에 보이는 뭔가처럼 각 가정Model.where(...)
nar8789

merge를 사용하기 전에 이것을 확인하십시오 -github.com/rails/rails/issues/33501
Aarthi

1

레일 5에 대한 능력이 or와 절을 where. 예를 들어.

User.where(name: "abc").or(User.where(name: "abcd"))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.