Ответ 1
Метод where
возвращает объект ActiveRecord::Relation
, и сам по себе этот объект не выдает запрос базы данных. Это где вы используете этот объект, который имеет значение.
В консоли вы, вероятно, это сделаете:
@person = Person.where(name: "Jason")
И затем blammo выдает запрос базы данных и возвращает то, что кажется массивом всех по имени Jason. Yay, Активная запись!
Но тогда вы делаете что-то вроде этого:
@person = Person.where(name: "Jason").where(age: 26)
И затем это вызывает другой запрос, но этот для людей, которых зовут Джейсон, которых составляет 26. Но он только выдаёт один запрос, так что, где был бы другой запрос?
Как и другие, это происходит, потому что метод where
возвращает прокси-объект. Он фактически не выполняет запрос и возвращает набор данных, если он не попросил этого сделать.
Когда вы запускаете что-либо в консоли, оно выводит проверенную версию результата того, что вы запустили. Если вы положите 1
в консоль и нажмите enter, вы получите 1
назад, потому что 1.inspect
- 1
. Магия! То же самое касается "1"
. У множества других объектов нет метода inspect
, и поэтому Ruby возвращается к тому, который находится на Object
, который возвращает что-то ужасное, как <Object#23adbf42560>
.
Каждый отдельный объект ActiveRecord::Relation
имеет метод inspect
, определенный на нем, так что он вызывает запрос. Когда вы пишете запрос в своей консоли, IRB вызовет inspect
по возвращаемому значению этого запроса и выведет что-то почти читаемое человеком, например массив, который вы увидите.
Если вы только что опубликовали это в стандартном Ruby script, тогда запрос не будет выполняться до тех пор, пока объект не будет проверен (через inspect
) или не будет повторен с помощью each
или не будет иметь метод to_a
призвал его.
До тех пор, пока не произойдет одна из этих трех вещей, вы можете направить на него столько операторов where
, сколько захотите, а затем, когда вы вызовете inspect
, to_a
или each
на нем, тогда это будет наконец, выполнить этот запрос.