Ruby on Rails:ActiveRecordを使用して2つの列でソートするにはどうすればよいですか?


91

2つの列で並べ替えたい、1つはDateTime(updated_at)、もう1つはDecimal(Price)

最初にupdated_atでソートできるようにしてから、同じ日に複数のアイテムが発生する場合は、Priceでソートします。

回答:


64

MySQLを使用していると仮定すると、

Model.all(:order => 'DATE(updated_at), price')

他の回答との違いに注意してください。updated_at列には、あなたがに基づいてソートする場合ので、フルタイムスタンプになるが更新された、あなたはタイムスタンプからちょうど日付部分を取得するための関数を使用する必要があります。MySQLでは、それはDATE()です。


7
結合が「あいまいな列」メッセージでランダムに壊れないようにするには、次のより堅牢なバージョンを使用する必要があります:order => ["DATE(#{table_name}.updated_at)", :price](これ:priceはシンボルです)
Jo Liss

私は私の注文の列をエスケープする必要がありましたorderので、同じよう:Model.all(:order => "day asc, `order` asc")
助成金


56
Thing.find(:all, :order => "updated_at desc, price asc")

トリックを行います。

更新:

Thing.all.order("updated_at DESC, price ASC")

Rails 3への道のりです。(ありがとう@cpursley


4
@Erikに感謝-この回答は古いので、現在表示されている方への警告は次のとおりです。このメソッドはRails 3.2から廃止されました。代わりにThing.allを使用してください=)
Abdo

正しい、これは私のためによく働い: Thing.all.order("updated_at DESC, price ASC")
cpursley

1
ソートされた値を小文字にする必要があるときに、更新が役に立ちましたThing.order("LOWER(name), number")
Nick

36

Active Record Query Interfaceを使用すると、クエリを並べ替えるだけの属性を指定できます。

models = Model.order(:date, :hour, price: :desc)

または、より具体的にしたい場合(@ zw963に感謝):

models = Model.order(price: :desc, date: :desc, price: :asc) 

おまけ:最初のクエリの後で、他のクエリを連鎖させることができます。

models = models.where('date >= :date', date: Time.current.to_date)

私はこれが古い記事であることを知っていますが、個人が複数形であることを知っているように個人的に変更modelmodelsます。ただの提案です。
Tass

1
より特別な例を編集する必要があると思います。たとえば、models = Model.order({price::desc}、{date::desc}、{price:asc})
zw963

誰かがこれを貼り付けて、未定義のメソッドエラーを見つけた場合、ここに小さなタイプミスがあります。それはする必要があります:asc代わりにascModel.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw

18

実際には、Active Recordを使用してそれを行う多くの方法があります。上記で言及されていないものは(さまざまな形式で、すべて有効です):

Model.order(foo: :asc).order(:bar => :desc).order(:etc)

多分もっと冗長かもしれませんが、個人的には管理しやすいと思います。SQLは1つのステップでのみ生成されます。

SELECT "models".* FROM "models" ORDER BY "models"."etc" ASC, "models"."bar" DESC, "models"."foo" ASC

したがって、元の質問の場合:

Model.order(:updated_at).order(:price)

データ型を宣言する必要はありません。ActiveRecordはこれをスムーズに行い、DBエンジンもそうします


Member.includes(:voter).order( "town_club asc")。order( "voters.last_name asc")
bkunzi01

1
投稿したSQLは対応していModel.order(foo: :asc).order(:bar => :desc).order(:etc)ますか?SQLの順序句の順序は、SQLで実行.to_sqlしたときに得られる順序とは逆です。
Qaz

1
@Qazこれはずっと前のことです。おそらくこれを修正する必要があると思います。後で再確認します。ありがとう。
Rubyレーサー


0

これらのどれも私にはうまくいきませんでした!ちょうど2日間、インターネットでトップとボトムを見て、解決策を見つけました!!

special_priceやmsrpなど、productsテーブルに多くの列があるとしましょう。これらは、ソートしようとしている2つの列です。

さて、まずモデルに次の行を追加します:

named_scope :sorted_by_special_price_asc_msrp_asc, { :order => 'special_price asc,msrp asc' }

次に、製品コントローラーで、検索を実行する必要がある場所を追加します。

@search = Product.sorted_by_special_price_asc_msrp_asc.search(search_params)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.