Как Rails ActiveRecord цепочка "где" предложения без нескольких запросов?
Я разработчик PHP, изучающий удивительность Ruby on Rails, мне нравится 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
Как это колдовство работает?
4 ответа:
The
where
метод возвращаетActiveRecord::Relation
"объект", и сам по себе этот объект не выдает запрос к базе данных. Это здесь вы используете этот объект, который имеет значение.в консоли, вы, вероятно, делаете это:
@person = Person.where(name: "Jason")
а то blammo он выдает запрос к базе данных и возвращает то, что кажется массив всех по имени Джейсон. Ура, Активная Запись!
но тогда вы делаете что-то вроде это:
@person = Person.where(name: "Jason").where(age: 26)
и тогда это выдает другой запрос, но это для людей, которые называются Джейсон, которым 26. Но это только выдача один запрос, так куда же делся другой запрос?
как предположили другие, это происходит потому, что
where
метод возвращает объект прокси. Он фактически не выполняет запрос и не возвращает набор данных, если его не просят об этом.при выполнении что-нибудь в консоль, она будет выводить проверенную версию результата того, что вы запустили. Если вы ставите
1
в консоли и нажмите enter, вы получите1
обратно, потому что1.inspect
и1
. Магия! То же самое касается"1"
. Множество других объектов не имеютinspect
метод определен и поэтому Ruby возвращается к одному наObject
который возвращает что-то жуть как<Object#23adbf42560>
.все до единого
Существует ряд методов, известных как" кикеры", которые фактически запускают запрос к базе данных. До этого они просто создают узлы AST, которые после запуска генерируют фактический SQL (или язык, на который компилируется) и запускают запрос.
посмотреть этот блог для более глубокого объяснения того, как это делается.