I think the key problem is that the ActiveRecord API is not aware of the ordering semantics . It just takes a string and bypasses the underlying database. Fortunately, Sqlite, MySQL, and PostgreSQL have no difference in order syntax.
I do not think that ActiveRecord can do this abstraction well, and it does not need to be done. It works well with relationship databases, but it is difficult to integrate with NoSQL, for example. MongoDB.
DataMapper , another well-known Ruby ORM, made a better abstraction. Take a look at the query syntax :
@zoos_by_tiger_count = Zoo.all(:order => [ :tiger_count.desc ])
The API knows about the semantics of ordering. By default, DataMapper will generate an SQL order statement:
https://github.com/datamapper/dm-do-adapter/blob/master/lib/dm-do-adapter/adapter.rb#L626-634
def order_statement(order, qualify) statements = order.map do |direction| statement = property_to_column_name(direction.target, qualify) statement << ' DESC' if direction.operator == :desc statement end statements.join(', ') end
However, an override at the DB adapter level is possible:
https://github.com/solnic/dm-mongo-adapter/blob/master/lib/dm-mongo-adapter/query.rb#L260-264
def sort_statement(conditions) conditions.inject([]) do |sort_arr, condition| sort_arr << [condition.target.field, condition.operator == :asc ? 'ascending' : 'descending'] end end
TL DR:
- You do not need to worry about the syntax problem if you use only SqlLite, Mysql and PostgreSQL.
- For a better abstraction, you can try DataMapper.
source share