Ленивая загрузка в 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'
Итак, запрос выполняется правильно?
Куда шла ленивая погрузка? Или я здесь что-то не хватает?
Ответы
Ответ 1
Консоль вызывает inspect
в результате любого введенного выражения, чтобы он мог отображать его для вас. inspect
- это одна из вещей, которая вызовет загрузку запроса. Если вы вместо этого выполняете
x = User.where(:first_name => 'John'); false
то вы не увидите никакого запроса, потому что на этот раз консоль вызывает проверку на false
вместо объекта привязки Active Record.
Ответ 2
Это интересный вопрос... Ответ заключается в том, что при выполнении чего-то в IRB/console он вызывает проверку на результирующий объект и затем распечатывает его. Если вы сделали что-то вроде:
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 не возвращается в консоли?
Ответ 3
Я проверил тест, используя sqllite3, чтобы попытаться выяснить, действительно ли поиск базы данных AR действительно выполнил запрос. Вот что я сделал:
rows=Customer.orders.find(1,2)
Тогда я сделал:
ActiveRecord::Base.remove_connection;
p rows
Я получил сообщение об ошибке, которая не установлена.
Я также попытался "p строк" сразу после запроса без удаления соединения и получил 2 строки, которые я ожидал.
Это было сделано с помощью activerecord-3.1.3. Мой вывод состоит в том, что в 3.1.3 base find ожидает выполнения запроса до тех пор, пока не будет достигнут доступ к массиву (Relation?).
Я новичок в Ruby, поэтому мой тест может быть неправильно спроектирован.