[ruby-on-rails] NOT NIL을 사용하는 상태의 레일

rails 3 스타일을 사용하면 어떻게 반대편을 쓸 수 있습니까?

Foo.includes(:bar).where(:bars=>{:id=>nil})

id가 nil이 아닌 곳을 찾고 싶습니다. 나는 시도했다 :

Foo.includes(:bar).where(:bars=>{:id=>!nil}).to_sql

그러나 그 결과는 다음과 같습니다.

=> "SELECT     \"foos\".* FROM       \"foos\"  WHERE  (\"bars\".\"id\" = 1)"

그것은 분명히 내가 필요한 것이 아니며 ARel의 버그처럼 보입니다.



답변

Rails 3으로이 작업을 수행하는 정식 방법 :

Foo.includes(:bar).where("bars.id IS NOT NULL")

ActiveRecord 4.0 이상이 추가 where.not되어 다음을 수행 할 수 있습니다.

Foo.includes(:bar).where.not('bars.id' => nil)
Foo.includes(:bar).where.not(bars: { id: nil })

테이블 사이의 범위를 작업 할 때 merge기존 범위를 더 쉽게 사용할 수 있도록 활용 하는 것이 좋습니다.

Foo.includes(:bar).merge(Bar.where.not(id: nil))

또한 includes항상 조인 전략을 선택하지는 않으므로 references여기에서도 사용해야 합니다. 그렇지 않으면 유효하지 않은 SQL로 끝날 수 있습니다.

Foo.includes(:bar)
   .references(:bar)
   .merge(Bar.where.not(id: nil))


답변

ARel의 버그가 아니며 논리의 버그입니다.

여기서 원하는 것은 :

Foo.includes(:bar).where(Bar.arel_table[:id].not_eq(nil))


답변

Rails4의 경우 :

따라서 원하는 것은 내부 조인이므로 조인 조건자를 사용해야합니다.

  Foo.joins(:bar)

  Select * from Foo Inner Join Bars ...

그러나 레코드의 경우 “NOT NULL”조건을 원하면 not 술어를 사용하십시오.

Foo.includes(:bar).where.not(bars: {id: nil})

Select * from Foo Left Outer Join Bars on .. WHERE bars.id IS NOT NULL

이 구문은 사용 중단을보고합니다 (문자열 SQL 스 니펫에 대해 이야기하지만 구문 분석기에서 해시 조건이 문자열로 변경 되었습니까?). 끝에 참조를 추가해야합니다.

Foo.includes(:bar).where.not(bars: {id: nil}).references(:bar)

감가 상각 경고 : 문자열 SQL 스 니펫에서 참조되는 테이블 (하나 중 하나 : ….)을 열망하는 것처럼 보입니다. 예를 들면 다음과 같습니다.

Post.includes(:comments).where("comments.title = 'foo'")

현재 Active Record는 문자열의 테이블을 인식하고 주석을 별도의 쿼리에로드하지 않고 주석 테이블을 쿼리에 참여시키는 것을 알고 있습니다. 그러나 완전한 SQL 파서를 작성하지 않고이 작업을 수행하는 것은 본질적으로 결함이 있습니다. 우리는 SQL 파서를 작성하고 싶지 않기 때문에이 기능을 제거하고 있습니다. 이제부터는 문자열에서 테이블을 참조 할 때 명시 적으로 Active Record에 알려야합니다.

Post.includes(:comments).where("comments.title = 'foo'").references(:comments)

답변

이것이 도움이되지는 않지만 Rails 4에서 나를 위해 일한 것은 확실하지 않습니다.

Foo.where.not(bar: nil)


답변

Rails 4를 사용하면 쉽습니다.

 Foo.includes(:bar).where.not(bars: {id: nil})

참조 :
http://guides.rubyonrails.org/active_record_querying.html#not-conditions


답변