> Custom percent-expressions would be a more elegant solution I think, allowing you to embed truly distinct mini-languages in Ruby: %date(5 days ago). Or %time(-12 hours), etc.
The issue there being that 1. it's going to become a pain to parse fast and 2. it starts looking a lot like genuine text, and thus people will want it localizable, thus bringing more of 1
ssmoot says he invented this, which is eminently readable but feels like being too leaky (what's the name of the deprecated gem that does that to AR already?):
1) User.where(:age.gt => 5)
ssmoot says this is better:
2) User.where { |user| user.age > 5 }
SQLAlchemy does it this way:
3) query.filter(User.name == 'ed')
which looks so much like how AR3.0 + ARel does it (and seriously AR::Base should delegate [] to arel_table):
4) User.where(User.arel_table[:age].gt 5)
and here's squeel's way:
5) User.where{age >= 5}
FTR, Django QuerySet does it by parsing kwargs (convention is double underscore => dot, which allows to 'call' methods on fields (pub_date__year) and joined relations (group__name)):
6) User.objects.filter(age__gt=5)
From a 'user' (i.e developer consuming the API) perspective I really like 1 and 5 because there is no redundancy (with which 2 is full of). Still when you're join()ing, you have to make ambiguous things explicit, and in that case 1 falls apart (you're not going to write :group_name, are you?), so while 5 is nice and allows for niceties like group.type, I am perfectly content with 4 because it's both stock Rails and quite readable, it's just that the full sized User.arel_table breaks the reading flow, and a bit redundant in the trivial case.
I'm not fond of stringifying stuff as resorting on parsing makes it less dynamic and more prone to abuse, and it we write strings we might as well write partial SQL.
Indeed ActiveSupport is a bad example because it extends by monkeypatching, but implements stuff that always apply (all strings are potentially camelizable, always, ever, and arguably integers can always be qualified with units) whereas Symbol#gt is nonsensical outside some specific scope.
The refinement situation is terrible because it performs poorly, leaks badly and makes things terribly inconsistent, especially with blocks passed around. I can't even begin to fathom the consequences of a block being called on an unexpected binding.
Looks quite similar to how SQLAlchemy does it, although it doesn't use a block: http://docs.sqlalchemy.org/en/rel_0_7/orm/tutorial.html#comm...
> Custom percent-expressions would be a more elegant solution I think, allowing you to embed truly distinct mini-languages in Ruby: %date(5 days ago). Or %time(-12 hours), etc.
The issue there being that 1. it's going to become a pain to parse fast and 2. it starts looking a lot like genuine text, and thus people will want it localizable, thus bringing more of 1