2011-11-15 15 views
4

のRails 3の関係をソートするには、我々はこれをしなければならない。Railsの3 Active Recordの関係順:使用ハッシュの代わりの文字列

User.where(:activated => true).order('id ASC') 

しかし、私はこれを考える:

User.where(:activated => true).order(:id => :asc) 

になるだろうフィールド名がエスケープされる方法はアダプタ(SqlLite vs Mysql vs PostgreSQL)に依存するはずなので、意味があります。

これに類似するものはありますか?

答えて

2

私が知る限り、この構文はActiveRecordに組み込まれていませんが、追加するのは難しいことではありません。 orderメソッドがlib/active_record/relation/query_methods.rbで定義されています。 ActiveRecordのAPIはセマンティックを注文を認識していない:

module ActiveRecord 
    module QueryMethods 
    def order(*args) 
     args.map! do |arg| 
     if arg.is_a? Hash 
      # Format a string out of the hash that matches the original AR style 
      stringed_arg 
     else 
      arg 
     end 
     end 

     super 
    end 
    end 
end 
2

私は重要な問題だと思う:理論的には、このような何かを行うことができるはずです。文字列を受け入れ、基になるデータベースにバイパスします。幸運なことに、Sqlite、MySQL、PostgreSQLはorder構文に違いがありません。

私はActiveRecordがこの抽象化をうまくやっているとは思わないし、それをする必要はありません。リレーションシップデータベースとうまく機能しますが、NoSQLとの統合は難しいです。 MongoDB。

DataMapper、別の有名なRuby ORMが、より良い抽象化を行いました。 Take a look at its query syntax

@zoos_by_tiger_count = Zoo.all(:order => [ :tiger_count.desc ]) 

APIは順序付け意味を認識しています。デフォルトでは、DataMapperのは、SQLのorderステートメントが生成されます。

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 

をしかし、それはDBアダプタ層で上書きすることが可能です:

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:

  • SqlLite、Mysql、PostgreSQLのみを使用している場合は、構文上の問題は心配する必要はありません。
  • DataMapperを使用すると、抽象性を向上させることができます。この特定のケースでは
0

、あなたはすべてのデータベースに注文すると「ASC」ビットをドロップする可能性が暗黙のうちに私は、これはあなたがしたいと思うケースをカバーしていないことを認識しています

Foo.order(:bar) 

を昇順ですorder by bar descを実行しますが、order by節の関数を使用しない限り、実際にはこれは大した問題ではありません。その場合、squeelのようなものが役に立ちます

関連する問題