2
1

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 1 year has passed since last update.

【Rails】nilを最後にソートしたい

Posted at

環境

Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16

状況

UserPostcategory_idの降順かつnilを最後にソートしたいとき、このように書くと

User.eager_load(:posts)
    .order('posts.category_id IS NULL')
    .merge(Post.order(category_id: :desc))
    .select('users.*', 'posts.category_id AS posts_category_id')

下記のエラーと

for SELECT DISTINCT, ORDER BY expressions must appear in select list

下記の警告が出る。
これについては伊藤さんの記事がとても参考になりました。

DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "posts.category_id IS NULL". Non-attribute arguments will be disallowed in Rails 6.1. This method should not be called with user-provided values, such as request parameters or model attributes. Known-safe values can be passed by wrapping them in Arel.sql().

エラー文についてはよくselectorderしたいカラムを指定すると解決するというようなことが書かれている事が多かったが、私の場合はすでに指定しているのにエラーが…。

解決法

降順でnilを最後にソートするにはDESC NULLS LASTを使う。

User.eager_load(:posts)
    .order('posts.category_id DESC NULLS LAST')
    .select('users.*', 'posts.category_id AS posts_category_id')

参考

Rails6.1からはnulls_firstnulls_lastが使えるのですごく便利そう。

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?