#Mixing and Matching Queries#
puts Product.where(:price => 5).
where(:name => "apple").
order(:created_at).
limit(55).
joins(:users).
where(:user => {:name => "richard"})
##Each method takes the output of the previous and adds to it##
When do we call the database? ActiveRecord uses lazyloading when querying the database Here we build the sql
prods = Product.where(:price => 5)
puts prods.class
=> ActiveRecord::Relation
Doesn't actually make a query until we call a method on prods Here we execute the sql
puts prods.first
=> #<Product id: 1,
user_id: 1,
name: "HD Electric Amplifier",
price: 5,
created_at: "date",
updated_at: "date">
We can call different methods on prods to trigger the desired sql query
puts prods.all
puts prods.each do |product|
puts product.name
end
a = Product.where(:price => 5)
b = a.where(:name = 'apple')
c = b.order(:created_at)
d = c.limit(55)
e = d.joins(:users)
f = e.where(:users => {:name => "richard"}).class
puts f.first
puts f.all
puts f.count
puts f.each do |thing|
puts thing.something
end
After you've hit the database, it's always an ARRAY or an OBJECT
No longer an ActiveRecord::Relation
prods = Product.where(:price => 5)
puts prods.class
=> ActiveRecord::Relation
puts prods.all.class
=> Array
You can see object/array vs. relation as explained above
puts prods.all.where(:name => "apple")
=> NoMethodError: undefined method 'where' for []:Array
You can see you cannot call methods on objects or arrays where the sql has already been executed. The all method returns an array, and the where method cannot be called on data that has been queried from the database. You cannot return an array of all products, and then execute sql to query for name being apple
What you are able to do is puts prods.where(:name => 'apple').all
This is because the where method has not executed any sql yet, so nothing has been queried from the database, so no object or array has been returned, yet. If you call the method where name is apple on all prods, it's going to look for the name apple in all prods...