35811


`Company` と `Disclosure`というモデルが有り `Company`

[code]

    class Company < ActiveRecord::Base
      has_many :disclosures, dependent: :destroy
    end
    
[/code]

の関係になっています。

ここで`Disclosure`は`published_at`という`datetime`のカラムを持つのですが、複数の`Company`を`Disclosure`の`published_at`カラムの最新の物を用いてソートするにはどのような方法があるでしょうか？

現在は`Company`に`latest_disclosure_published_at`というソート用のカラムを追加し、`Disclosure`の更新時に`Company`側の情報を更新しています。

`Company`にカラムを追加せずにこのようなソートをするもっと良い方法はありますか？

## 追記

@yasu さんに教えて頂いた方法でローカルではできたのですが、サーバー上で試してみた所エラーが出てしまいました。

[code]

    PG::GroupingError: ERROR:  column "companies.code" must appear in the GROUP BY clause or be used in an aggregate function`
    
[/code]

サーバー上とローカルで`Postgres`のバージョンが異なってしまっているのですが、それが原因なのでしょうか…？

[code]

    Company.joins(:disclosures).
    group('companies.id, companies.code').
    select('companies.id, companies.code, MAX(disclosures.published_at) disclosure_published_at')
    
[/code]

のように`select`するカラムを全て`group`で指定すれば呼び出せるようですが、できれば`*`で一括で指定したいです。

### サーバー上(

psql --version  
psql (PostgreSQL) 8.4.20

psql --version  
psql (PostgreSQL) 9.5.2


CC BY-SA 3.0
2017-06-22T03:53:37.813
35796
2017-06-28T01:29:42.047
2017-06-27T11:33:38.083
3271
3271
question
ruby-on-rails postgresql
has_many関係を持つ親のモデルを子のモデルに基づいてソートする方法


JOIN してこんな感じかなあ...

[code]

    Company
      .joins(:disclosures)
      .group("companies.id")
      .select("companies.*, MAX(disclosures.published_at) disclosure_published_at")
      .order("MAX(disclosures.published_at)")
    
[/code]

`MAX(disclosures.published_at)` の値を取るには特異メソッドの `disclosure_published_at`
を使ってください。

**追記**

`GROUP BY` で指定した以外のカラムを `SELECT` で使うことは標準SQLとして正しくない方法で、私の回答があまりよくありませんでした。

カラムをいちいち指定するのも面倒なので、こんな感じの妥協案を。

[code]

    company_cols = Company.column_names.map { |name| "#{Company.table_name}.#{name}" }
    Company
      .joins(:disclosures)
      .group(company_cols)
      .select(*company_cols, "MAX(disclosures.published_at) disclosure_published_at")
      .order("MAX(disclosures.published_at)")
    
[/code]


CC BY-SA 3.0
2017-06-22T09:31:33.307
35811
2017-06-28T01:29:42.047
2017-06-28T01:29:42.047
76
76
35796
answer