ProgramingTip

Rails ActiveRecord는 여러 쿼리없이 "where"절을 어떻게 연결합니까?

bestdevel 2020. 11. 7. 10:18
반응형

Rails ActiveRecord는 여러 쿼리없이 "where"절을 어떻게 연결합니까?


저는 Ruby on Rails의 경이로움을 배우는 PHP 개발자이고, ActiveRecord를 좋아하고 정말 흥미로운 것을 발견했습니다. ActiveRecord 메서드가 쿼리를 실행하기 위해 메서드 체인의 끝을 감지하는 방법입니다.

@person = Person.where(name: 'Jason').where(age: 26)

# In my humble imagination I'd think that each where() executes a database query
# But in reality, it doesn't until the last method in the chain

이 마법은 어떻게 작동합니까?


where메서드는 ActiveRecord::Relation개체를 반환하며 자체 데이터베이스 쿼리를 실행하지 않습니다. 그건 어디 당신은 문제가 발생하는 것을 사용합니다.

콘솔에서 아마도 다음을 수행 할 것입니다.

@person = Person.where(name: "Jason")

그런 다음 blammo 는 데이터베이스 쿼리를 실행하고 Jason이라는 모든 사람의 배열로 보이는 것을 반환합니다. 예, 액티브 레코드!

하지만 다음과 같이합니다.

@person = Person.where(name: "Jason").where(age: 26)

그리고 또 다른 쿼리를 발행합니다. 그러나 26 세인 Jason이라고하는 사람들을위한 것입니다. 그러나 그것은 단지 하나의 쿼리 만을 발행하고 있습니다. 그래서 다른 쿼리는 어디로 갔습니까?


다른 사람들이 제안했듯이 where메서드가 프록시 개체를 반환 하기 때문에 이런 일이 발생 합니다. 요청하지 않는 한 실제로 쿼리를 수행하고 데이터 세트를 반환하지 않습니다.

콘솔에서 무엇이든 실행 하면 실행 한 결과의 검사 된 버전이 출력됩니다. 당신이 넣을 경우 1콘솔과 키를 누르십시오, 당신은 얻을 1것이 다시 1.inspect입니다 1. 마법! 동일은 간다 "1". 다른 개체의 다양한는없는 법 inspect정의와 루비가에 하나 떨어지면 Object뭔가를 반환하는 무시한 처럼 <Object#23adbf42560>.

모든 단일 ActiveRecord::Relation개체에는 inspect쿼리가 발생하는 정의가 있습니다. 콘솔에서 쿼리를 호출 할 때 IRB는 inspect해당 쿼리의 반환 값을 호출 하고 사용자가 볼 수있는 배열과 같이 거의 사람이 읽을 수있는 것을 출력합니다.


표준 Ruby 펼치기에서 선언 할 때 객체가 검사 (를 통해 inspect)되거나를 사용하여 반복 each되거나 메소드 to_a가 호출 될 쿼리가 실행되지 않습니다 .

그 세 가지 중 하나가 일어날 때까지, 당신은 체인 많은 수 where그것의 문은 당신이 좋아하는 것 같이이 때 다음 을 수행 전화 inspect, to_a또는 each거기에, 그것은 결국 해당 쿼리를 실행합니다.


실제로 데이터베이스에 대한 쿼리를 실행하는 "키커"라고하는 여러 메서드가 있습니다. 그 전에는 AST 노드를 생성하기 만하면 한 번 실행하면 SQL (또는 실행되는 언어)을 생성하고 쿼리를 실행합니다.

이 작업을 수행하는 방법에 대한 자세한 설명은 이 블로그 게시물참조하십시오 .


코드를 읽을 수 있도록 여기서 한 가지 개념은 프록시 패턴입니다.

@person은 실제 개체가 아니라이 개체에 대한 프록시이며 속성이 필요할 때 아마도 활성 레코드가 마지막으로 쿼리를 실행합니다. Hibernate는 동일한 개념을 가지고 있습니다.


너무 늦었을 수도 있고 해시를 사용할 수 있습니다.

@person = Person.where({name: "Jason", age: 26})

결과 쿼리 :

SELECT "person".* FROM "person"  WHERE "person"."name" = 'Jason' AND "person"."age" = 26

참고 URL : https://stackoverflow.com/questions/10747106/how-does-rails-activerecord-chain-where-clauses-without-multiple-queries

반응형