6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Rails】関連する別テーブルのカラムが特定の値のレコードをソートで上位に持って来る方法

Last updated at Posted at 2015-03-28

Railsで、has_manyなどで関連している別テーブルのカラムの値が特定の値のものを上位に持って来ようと色々試して失敗したんですが、最終的にこのやり方でうまくいきました。ユースケースとしては、ブログ記事の一覧を取得しようとした時に、特定のユーザーからのコメントがある記事を上位に表示したい場合などが考えられます(そもそも、そんな状況ないとか言わないで・・)。

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :comments
end

というようなモデルを考えた時に、Postモデルに次のようなスコープを作ります。

post.rb
scope :prioritize_users_comment, lambda { |user_id|
  includes(:comments).order("
    case
      when comments.user_id = :user_id then 1
      else 0
    end desc
  ", user_id: user_id).references(:comments)
}

すると、

Post.prioritize_users_comment(7)

とすれば、id:7のユーザーのコメントがついた記事が上位にソートされて返ってきます。ポイントはSQLのCASE式を使うこと、includes,referencesを使ってLEFT OUTER JOINすることですね。
もっと良いやり方があったら教えて下さい〜

6
9
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
6
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?