jgaskins/perpetuity

More Enumerable-like syntax

Closed this issue · 2 comments

We have a Mapper#select, which is great, but I think we can do even better.

  • #find_all as an alias for #select
  • #find/#detect already exists, and I like it as a shorthand, but if we could make it optionally take a block like #select instead, that would be even better. To clarify, I don't want to get rid of Mapper#find(id). The good news is, this is trivial: find is just select(&block).limit(1).first. Bam.
  • #map/#collect to only return the specified attribute. This would require implementing this behavior into the DB adapter, as well.
  • #reject to find non-matching criteria. This would also require a DB-adapter implementation. For MongoDB, I believe we can simply use { '$not' => query }. Need to check that, though.
  • #count should accept an optional block for criteria.
  • #min_by/#max_by: We may need to accept a symbol rather than a block here, or convert #sort to take a block, because we'll need to use #sort to determine min and max.
  • #take as an alias for #limit/#per_page
  • #drop(n) to skip the first n objects. This is similar to #page, except #drop won't depend on the value provided to #per_page/#limit.
  • #any?/#all?/#one?/#none? based on #count
  • #entries as an alias for #to_a

Most of the rest of Enumerable can be done on the resulting array.

Both Mapper and Retrieval will need to implement this functionality. This raises a red flag in my mind and means we may need to merge the classes. Maybe merge the two classes so that using Enumerable methods just instantiates a new Mapper instead of a Retrieval?

The idea behind Retrieval was to represent a result set, but the result set is actually the array returned from Retrieval#to_a. The current implementation of Retrieval doesn't represent a query result at all; it's just query metadata.

I'll experiment with it a bit and see what I come up with.

Completed find, count, and reject as well as find_all and detect aliases while pairing with @kevinsjoberg. The diff.

map will not be implemented due to potential confusion about it yielding a database-query object, which may not work like an actual object in the collection.

Everything but min_by and max_by is implemented. Closing.