Reputation: 11374
I'd like to save a query, then build on top of it, then execute it.
For example, somehow
query = Post.order('likes DESC') # buffer the query
query = query.limit(3) # add on top of it
query.run # run it - this is the wrong syntax fyi
Can this be done? What's the right syntax?
PS. I'm not sure if "buffer" is the right word, please correct me if I'm wrong.
Thanks!
Upvotes: 3
Views: 1963
Reputation: 491
You can use ActiveRecord::Relation#load
method to force database hit:
https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-load
Upvotes: 0
Reputation: 930
You don't need any "buffers" when building queries with ActiveRecord in Rails 3 because it uses Arel. Your query = Post.order('likes DESC')
gives you instance of ActiveRecord::Relation. This object contains information about query, but not an actual data. To get data you can invoke .first
or .all
methods for example. It's way how rails framework (>= 3.0) implements so called "lazy initialization". It means that ActiveRecord::Relation is a kind of proxy. Real query to the database goes only when you're trying to get some fields of your model (or when you force load data with .all, .first
, .last
etc). Until this action you can build your chain of filtering conditions and be sure that you do not "disturb" database.
Your code may be like this:
query = Post.order('likes DESC') # ActiveRecord::Relation object with info about your query
query = query.limit(3) # adds more filtering options
@posts = query.all # here ActiveRecord takes data from the database
#239 ActiveRecord::Relation Walkthrough will give you more understanding about ActiveRecord::Relation
Upvotes: 4
Reputation: 11904
That's exactly how ActiveRecord works. When it hits an iterator or some other non-AR method, it calls the database using the built-up query. It works a little different in the console, because I believe the .inspect
method is called to display the output after you press return.
It's fine to do what you've proposed.
Upvotes: 2
Reputation: 38032
If you are using AREL and Rails 3 this happens automatically. AREL will built up a query as you chain options and execute the query when you call .all
or start accessing data through any other means.
Upvotes: 3