Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created January 6, 2014 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahoward/8285529 to your computer and use it in GitHub Desktop.
Save ahoward/8285529 to your computer and use it in GitHub Desktop.
On Mon, Jan 6, 2014 at 8:28 AM, MM <m@dojo4.com> wrote:
> I don't understand why these results are different:
>
> irb(main):024:0> Post.page(1).per(5).count
>
> MOPED: 127.0.0.1:27017 COMMAND database=dj4-development
> command={:count=>"posts", :query=>{}} (0.4470ms)
>
> => 128
>
> irb(main):025:0> Post.page(1).per(5).to_a.count
>
> MOPED: 127.0.0.1:27017 QUERY database=dj4-development
> collection=posts selector={} flags=[:slave_ok] limit=5 skip=0 fields=nil
> (0.8380ms)
>
> MOPED: 127.0.0.1:27017 KILL_CURSORS cursor_ids=[4008368529231388]
> (0.1040ms)
>
> => 5
>
>
> what gives?
>
>
> -- m
>
try this
Post.page(1).per(5).class
Post.page(1).per(5).to_a.class
and also don't forget that, in irb, you always calling '.inspect' in
whatever you are looking at for a string representation
summary: back in the day one had to be very careful about shit like this
@posts = Post.all.to_a
@posts.first(10).each ....
because that first line slurps *the entire set from the db into memory*.
so in later ruby ORMs queries are generally lazy, firing only when someone
calls something like 'each' on them, aka
Post.all #=> a promise, does nothing
Post.all.each ... #=> starts iterating objects from the db
so here the pagination method
Post.page(1).per(5)
just builds the promise of something that, when iterated over, will give
the correct results. in particular it does not 'load 5 things from the db'
this seems a teeny bit odd but if you think about implementing
Post.all.count
so as to NOT first load every damn post in the db you'll realize just how
tricky it is
in ruby http://sequel.jeremyevans.net/ was the first library to abstract
this relational calculus - not someone subsumed by
https://github.com/rails/arel
required reading
http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx
also interesting to consider is that, for mongoid and mongo adapters the
authors had to *totally recreate this from scratch*. the 'rel' in 'arel'
means 'relational'.
the main reason this is important is that, despite what MVC fans think,
it's ***enormously*** difficult to do the following on a controller view
stack
- cache a view
- perform the queries in the controller only if the view is requires it
(otherwise what is the point of caching!)
in php this is damn easy: you just do the query in the view and cache it.
done. in rails, or any mvc stack, the abstract layer of the controller,
while nice to look at and manage, gives like a 100x performance hit. this
is the reason for lazy queries and the subject of our next quiz in
3...2...1....
-- a - http://dojo4.com - @drawohara
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment