Criteria for ActiveRecord
Over the last couple of days I’ve been working on a Criteria for ActiveRecord. The concept is quite simple; rather than writing strings of SQL to pass to the find() method, we build the criteria using an object-orientated approach. Anyone who has used Hibernate, Torque, Propel et al will know how powerful and useful this can be.
For example, imagine you have a series of filters, all of which may, or may not, add constraints or expressions to your query. Each filter will need to append it’s own SQL to the end of any previously generated SQL and may even need to introspect the existing SQL to determine if its doubling up on statements or resolve potential conflicts.
With Criteria this becomes simpler. For example:
criteria = Criteria.new criteria.and do |c| c.or User.role.eq(:admin) c.or User.active.eq(false) c.or User.createdAt.gt(10.hours.ago) end criteria.and do |c| c.or User.role.eq(:editor) c.or User.active.eq(true) c.or do |c2| c2.and User.createdAt.gt(20.days.ago) c2.and User.createdAt.lt(10.hours.ago) end end users = User.find(:all, criteria)
We could, at any point, introspect the state of criteria by calling:
criteria.ands.each do |c| put "AND #{c}" end criteria.ors.each do |c| put "OR #{c}" end
And, finally, we can remove arbitrary bits of criteria:
criteria.ands.delete_at 2
I hope to have a release out very soon, but for the time being some more examples and API docs are on the Criteria project page on RubyForge