LoginSignup
7
5

More than 5 years have passed since last update.

ActiveRecordのorderメソッドに引数を複数渡す場合の具体例

Last updated at Posted at 2019-02-24

自分のブログの転載記事です。

はじめに

ActiveRecordのorderメソッドに引数を複数渡せることは有名だと思います。
ですが「複数の値を渡すとどのようにソートされるのか」について具体的に言及している記事が少ないように感じたので、簡単な例を挙げてまとめてみたいと思います。
(自分の検索能力が低いだけかも知れませんが)

検証準備

複数のカラムを持つUserテーブルを定義して、以下のレコードを格納します。

id name gender role
1 Alice 2 1
2 Bob 1 1
3 Carol 2 2
4 Dave 1 2

カラムはそれぞれ、名前、性別、ロールです。それぞれ単なる検証用の値なので、深い意味はありません。
そしてUserモデルの中に、以下のメソッドを定義します。

class User < ApplicationRecord
  def print
    puts "id:#{id} name:#{name} gender:#{gender} role:#{role}"
  end
end

これで準備は完了です。

引数が一つの場合

まずは簡単な例からやってみましょう。nameをorderの引数にする場合です。

# 名前昇順
irb(main):001:0> users = User.all.order(:name)
irb(main):002:0> users.each {|user| user.print}
id:1 name:Alice gender:2 role:1
id:2 name:Bob gender:1 role:1
id:3 name:Carol gender:2 role:2
id:4 name:Dave gender:1 role:2

ユーザーの名前はアルファベット順になっているので、このような結果になります。
genderやroleを引数にした場合は以下のとおりです。

# 性別昇順
irb(main):001:0> users = User.all.order(:gender)
irb(main):002:0> users.each {|user| user.print}
id:2 name:Bob gender:1 role:1
id:4 name:Dave gender:1 role:2
id:1 name:Alice gender:2 role:1
id:3 name:Carol gender:2 role:2

# ロール昇順
irb(main):003:0> users = User.all.order(:role)
irb(main):004:0> users.each {|user| user.print}
id:1 name:Alice gender:2 role:1
id:2 name:Bob gender:1 role:1
id:3 name:Carol gender:2 role:2
id:4 name:Dave gender:1 role:2

gender, roleの場合、それぞれが1, 2という順で並びます。

引数が2つの場合

ここからが本題です。引数が複数渡された場合、どのような順序になるのでしょう。

# 性別昇順、ロール昇順
irb(main):001:0> users = User.all.order(:gender, role: :asc)
irb(main):002:0> users.each {|user| user.print}
id:2 name:Bob gender:1 role:1
id:4 name:Dave gender:1 role:2
id:1 name:Alice gender:2 role:1
id:3 name:Carol gender:2 role:2

# 性別昇順、ロール降順
irb(main):003:0> users = User.all.order(:gender, role: :desc)
irb(main):004:0> users.each {|user| user.print}
id:4 name:Dave gender:1 role:2
id:2 name:Bob gender:1 role:1
id:3 name:Carol gender:2 role:2
id:1 name:Alice gender:2 role:1

最初に渡される引数は性別で、後に渡される引数はロールです。
その場合、性別がまず優先してソートされ、1が先、2が後という順序になります。
その後、第二引数として渡されたロールの順序によってソートされているのがわかるでしょうか。

つまりorderメソッドに引数を複数渡す場合、「先に渡した引数が優先条件としてソートされ、その後、後に渡した引数を条件としてソートされる」ということになります。

もうひとつの例として、ロール、性別の順で引数を渡した場合を見てみます。

# ロール降順、性別昇順
irb(main):001:0> users = User.all.order(role: :desc, gender: :asc)
irb(main):002:0> users.each {|user| user.print}
id:4 name:Dave gender:1 role:2
id:3 name:Carol gender:2 role:2
id:2 name:Bob gender:1 role:1
id:1 name:Alice gender:2 role:1

# ロール降順、性別降順
irb(main):001:0> users = User.all.order(role: :desc, gender: :desc)
irb(main):002:0> users.each {|user| user.print}
id:3 name:Carol gender:2 role:2
id:4 name:Dave gender:1 role:2
id:1 name:Alice gender:2 role:1
id:2 name:Bob gender:1 role:1

第一引数がロールの降順なので、2→1としてソートされた後、性別でソートされていますね。

以上、複数の引数でorderした場合の簡単な例でした。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5