2016-10-18 4 views
2

私はUsersAppointmentsの2人のモデルがあるとします。ユーザーhas_manyの予定です。特定の属性とのモデルの関連付けの順番で並べ替えます。

アポイントは、typeAtypeBの2種類があります。

typeBアポイントの合計でユーザーを注文するクエリを書くにはどうすればいいですか?

私はcounter_cacheを調べましたが、関連付けの数をカウントしているように見えます(この場合、ユーザーが持つ予定の数)。特定の種類の予定のカウントは許可されていません。 joins

+0

[RailsのActiveRecordの3:組合の回数順]の可能な重複(http://stackoverflow.com/questions/8696005/rails-3-activerecord-order-by-count-on-association) –

答えて

3

(INNER JOINを)あなたが関連する少なくとも一つの予定持つユーザーのみ、取得します:あなたが使用している場合

User.joins(:appointments) 
    .where(appointments: { type: 'typeB' }) 
    .group('users.id') 
    .order('count(appointments.id) DESC') 

includes(LEFT OUTER JOINをする)代わりに、あなたがリストを取得しますリストの末尾に'typeB'というアポイントメントを持たないユーザーがいることを確認します。

+0

'join 'の代わりに' includes'を使うと、リストの一番下に 'typeB'がないすべてのユーザーが返されます。この答えは両方のオプションを表示する必要がありますか? – SteveTurczyn

+0

@SteveTurczyn私はそれを編集することができます、それは意味をなさないと思います –

+1

ところで、いい答えです。 – SteveTurczyn

1

データベースのサイズと複雑さによっては、テーブルの結合ではなく2つのクエリを実行する方が良い場合があります。結合をスキップする場合は、1つの選択クエリからIdsの順番を取得し、次に2番目のクエリからレコードを取得することができます。

ordered_user_ids = Appointments.select('user_id, count(1) AS N') 
.where(:type => 'typeB').group(:user_id).order('N desc').collect(&:user_id) 

# find users keeping the order of the users intact 
User.find(ordered_user_ids, :order => "field(id, #{ordered_user_ids.join(',')})") 
関連する問題