11786


railsのあるmodelで複数のscopeを使いオブジェクトの並べ方を定義しています。

[code]

    scope :scope_A, -> { where(...).order('created_at DESC') }
    scope :scope_B, -> { ......... }
    scope :scope_C, -> { ........ }
    
[/code]

この３つのscope結果を上から順番に取り出して結合した結果を得るにはどうすればいいのでしょうか？  
例えばscope_A の結果が `A1,A2,A3`  
scope_B の結果が `B1,B2,B3`  
scope_C の結果が `C1,C2,C3` とすると  
結合結果が `A1,A2,A3,B1,B2,B3,C1,C2,C3` のように並べたいと考えています。


CC BY-SA 3.0
2015-06-26T08:32:16.033
11774
2015-06-27T02:32:47.753
2015-06-26T14:22:08.140
9202
9202
question
ruby-on-rails ruby rails-activerecord
複数のscopeの結果をひとつにまとめる方法は？


PostgreSQLのように行番号（ここでは ROW_NUMBER）が簡単に取れるRDBMSを使うことが前提ですが、こんなふうに実装するのはどうでしょうか？

[code]

    class Language
      scope :ruby, ->{ where(lang_type: :ruby).order(:id) }
      scope :perl, ->{ where(lang_type: :perl).order(:id) }
      scope :java, ->{ where(lang_type: :java).order(:id) }
    
      def self.order_by_lang_type
        full_sql = %w(ruby perl java).map.with_index {|type, i|
          sql = self.send(type).select("#{i} AS type_no, ROW_NUMBER() OVER() AS row_no, languages.*").to_sql
          "SELECT * FROM (#{sql}) AS t_#{i}"
        }.join(" UNION ALL ") + " ORDER BY type_no, row_no"
    
        self.find_by_sql(full_sql)
      end
    end
    
[/code]

参考にしたページはこのあたりです。

  * [Rails - ActiveRecordでunion使いたい - Qiita](http://qiita.com/kwgch/items/11d88d50bdfb183d6207)
  * [ms access - SQL Query - Using Order By in UNION - Stack Overflow](https://stackoverflow.com/questions/213851/sql-query-using-order-by-in-union)

がんばればscopeにもできるようです。

[code]

    scope :order_by_lang_type, -> {
      full_sql = %w(ruby perl java).map.with_index {|type, i|
        sql = self.send(type).select("#{i} AS type_no, ROW_NUMBER() OVER() AS row_no, languages.*").to_sql
        "SELECT * FROM (#{sql}) AS t_#{i}"
      }.join(" UNION ALL ")
    
      select("t.*").from(Arel.sql("(#{full_sql}) as t")).order('t.type_no, t.row_no')
    }
    
[/code]

参考ページ： [ruby on rails - Turn SQL query into ActiveRecord Relation - Stack
Overflow](https://stackoverflow.com/questions/16324305/turn-sql-query-into-
activerecord-relation)

とはいえ件数が少なければ単純に "+" で連結するのありかもしれません。

[code]

    def self.order_by_lang_type
      ruby + perl + java
    end
    
[/code]


CC BY-SA 3.0
2015-06-26T23:01:00.650
11786
2015-06-27T02:32:47.753
2017-05-23T12:38:56.083
-1
85
11774
answer