Rails: Order with nulls last

后端 未结 10 1469
悲哀的现实
悲哀的现实 2020-11-30 19:12

In my Rails app I\'ve run into an issue a couple times that I\'d like to know how other people solve:

I have certain records where a value is optional, so some recor

相关标签:
10条回答
  • 2020-11-30 19:53

    Adding arrays together will preserve order:

    @nonull = Photo.where("collection_id is not null").order("collection_id desc")
    @yesnull = Photo.where("collection_id is null")
    @wanted = @nonull+@yesnull
    

    http://www.ruby-doc.org/core/classes/Array.html#M000271

    0 讨论(0)
  • 2020-11-30 19:54

    It seems like you'd have to do it in Ruby if you want consistent results across database types, as the database itself interprets whether or not the NULLS go at the front or end of the list.

    Photo.all.sort {|a, b| a.collection_id.to_i <=> b.collection_id.to_i}
    

    But that is not very efficient.

    0 讨论(0)
  • 2020-11-30 20:03
    Photo.order('collection_id DESC NULLS LAST')
    

    I know this is an old one but I just found this snippet and it works for me.

    0 讨论(0)
  • 2020-11-30 20:06

    For posterity's sake, I wanted to highlight an ActiveRecord error relating to NULLS FIRST.

    If you try to call:

    Model.scope_with_nulls_first.last
    

    Rails will attempt to call reverse_order.first, and reverse_order is not compatible with NULLS LAST, as it tries to generate the invalid SQL:

    PG::SyntaxError: ERROR:  syntax error at or near "DESC"
    LINE 1: ...dents"  ORDER BY table_column DESC NULLS LAST DESC LIMIT...
    

    This was referenced a few years ago in some still-open Rails issues (one, two, three). I was able to work around it by doing the following:

      scope :nulls_first, -> { order("table_column IS NOT NULL") }
      scope :meaningfully_ordered, -> { nulls_first.order("table_column ASC") }
    

    It appears that by chaining the two orders together, valid SQL gets generated:

    Model Load (12.0ms)  SELECT  "models".* FROM "models"  ORDER BY table_column IS NULL DESC, table_column ASC LIMIT 1
    

    The only downside is that this chaining has to be done for each scope.

    0 讨论(0)
提交回复
热议问题