Мързеливо зареждане в Rails 3.2.6

Намерих в няколко ресурса онлайн, отколкото когато правя неща като:

cars = Car.where(:colour => 'black')

Заявката не се изпълнява, докато не направите нещо като:

cars.each {|c| puts c.name } 

Въпреки това, в моя проект Rails 3.2.6, когато направя следното в конзолата:

User.where(:first_name => "John")

Получавам следното:

 User Load (1.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`first_name` = 'John'

И така, заявката се изпълнява нали?

Къде отиде мързеливото зареждане? Или пропускам нещо тук?


person Hommer Smith    schedule 28.07.2012    source източник


Отговори (3)


Конзолата извиква inspect на резултата от всеки израз, който въвеждате, за да може да ви го покаже. inspect е едно от нещата, които ще задействат натоварването на заявката. Ако вместо това го направите

x = User.where(:first_name => 'John'); false

тогава не трябва да виждате заявка, защото този път конзолата извиква инспекция на false вместо на обекта за релация Active Record.

person Frederick Cheung    schedule 28.07.2012
comment
Това е една от онези ситуации, при които изследването в динамичната среда на конзолата (обикновено плодотворно начинание) всъщност може да доведе до объркване относно това как работи ActiveRecord. Знам за това поведение на мързеливо зареждане, но въпреки това понякога се спъвам от това. Наистина ми харесва твоята; фалшива идея. Ще се опитам да направя тази част от мускулната си памет, когато работя в конзолата. - person George Armhold; 06.12.2013
comment
Благодаря за страхотния отговор! Какви точно неща биха задействали зареждане на заявка на обект ActiveRecord::Relation? pluck, кажи? - person Bad Request; 09.01.2015
comment
@kitkat pluck изпълнява заявка, която просто връща стойностите на колоните, а не AR обекти. Всичко като each, map, reject, to_a и т.н. ще доведе до зареждане на релацията. По принцип липсва метод в Relation, който ще зареди целта и ще препрати извикването на метода към нея. - person Frederick Cheung; 10.01.2015

Това е интересен въпрос... Отговорът е, че когато се изпълнява нещо в IRB/конзолата, той извиква проверка на получения обект и след това го отпечатва. Ако сте направили нещо като:

User.where(:first_name => "John").class

трябва да получите обратно обект ActiveRecord::Relation.

Така че мързеливото зареждане за Rails все още се поддържа, това е просто начинът, по който работи конзолата.

Надявам се това да помогне.

Източник(и): 1) https://rails.lighthouseapp.com/projects/8994/tickets/4951-rails-console-executes-where-queries-without-lazy-loading 2) Защо връзката Active Record не се връща в конзолата?

person Community    schedule 28.07.2012

Проведох тест с помощта на sqllite3, за да се опитам да разбера дали намирането на AR Base действително е извършило незабавно запитване. Ето какво направих:

rows=Customer.orders.find(1,2)

Тогава направих:

ActiveRecord::Base.remove_connection;
p rows

Получих грешка, че връзката не е установена.

Също така опитах "p rows" веднага след заявката без премахване на връзката и получих 2 реда, които очаквах.

Това беше направено с activerecord-3.1.3. Моето заключение е, че в 3.1.3 base find изчаква да изпълни заявката, докато масивът (релация?) бъде достъпен.

Нов съм в Ruby, така че тестът ми може да не е проектиран правилно.

person pyhacker    schedule 19.03.2015
comment
Може да преместите заключението най-горе, така че хората да не бъркат това с публикация „И аз имам този проблем“. - person Jeffrey Bosboom; 19.03.2015