[LRUG] ActiveRecord::Relation#as_batches - like find_each but honours order, limit, offset
Viktor Tron
viktor.tron at gmail.com
Sat May 5 11:58:32 PDT 2012
Hi Daniel,
Thanks for the great gem.
Indeed testing by parsing logs seems just as volatile as it is an overkill.
I suggest that to test batchwise calling you should just replicate rails
find_each or find_in_batches tests,
which is checking how many times sql query was called simply using the
assert_queries method:
https://github.com/rails/rails/blob/9066e3402548d365dc7cf2abda8e7cd64370675c/activerecord/lib/active_record/test_case.rb
Testing correct order and offset restrictions is easy by checking on the
models manipulated directly without even looking at sql calls.
Roughly:
- define a test model with an ordered_attr
- populate with instances @first, ... @nth with ordered_attr as 0, ..., n
- invoke batches like
@invoked = []
Model.order(:ordered_attr,:desc).as_batches do |m|
@invoked << m.ordered_attr
end
- and test that assert_equal(@invoked, (0..n).to_a.reverse)
- (and maybe test order without the order clause to make sure it is not by
pure chance :)
HTH
Vik
On Sat, 05 May 2012 17:44:53 +0100, Daniel Barlow <dan at telent.net> wrote:
> An almost[*]-a-gem announcement, and a question:
>
> The internet confirms that I'm not the only person who's attempted to
> use find_each to get only part of a result set, and been disappointed
> to find that it doesn't support order, limit or offset - any or all of
> which might be useful if you want to consume a large but unknown
> number of records without potentially instantiating several million
> ActiveRecord::Base objects at once. So I wrote something that does.
>
> ar-as-batches : https://github.com/telent/ar-as-batches/ lets you do e.g.
>
> User.where(country_id:
> 44).order(:joined_at).offset(200).as_batches do |user|
> user.party_all_night!
> end
>
> and it works much as you'd expect
>
> And now the question: to test it I create an in-memory sqlite database
> and tell activerecord to log its sql queries to a Logger wrapping a
> StringIO, then afterwards I match regexps on the string to see what
> queries were actually sent. I cannot help feeling that there must be
> a Better Way: is there, and what?
>
> https://github.com/telent/ar-as-batches/blob/master/test/as-batches-test.rb
>
> This is the first time I've really done anything with ActiveRecord
> innards, so all suggestions welcome
>
>
> -dan
>
> [*] "almost" meaning there's a gemspec in the repo and you can include
> it with a :git entry in your Gemfile
More information about the Chat
mailing list