19

私はレールアプリを持っています:

user has_many :projects

user has_many :tasks, :through => :projects

project has_many :tasks

各タスクにはマイルストーンの日付があります。

私が使用している次のマイルストーン日付でプロジェクトの詳細の表を表示するには:

@projects = current_user.tasks.joins(:project).select("distinct on (projects.id) projects.*, tasks.*").reorder("projects.id, tasks.milestone ASC")

これはうまくいきます。

私は今、テーブルの列をソートできるようにしたいと考えています。

PostgresDISTINCT ONはソート可能ではないため、別の select ステートメントでラップする必要があります。つまり、SELECT * FROM (SELECT DISTINCT ON....) ORDER BY column_3

注文されている列は、必要に応じてSQLに組み込むことができると思いました。つまり、(プロジェクト名DESCで注文するため):

@projects = current_user.tasks.joins(:project).select("distinct on (projects.name) projects.*, tasks.*").reorder("projects.name DESC, tasks.milestone ASC")

これは機能しますが、マイルストーンで注文できるようにしたいのですが、そのようには機能しません。

Railsクエリを変換して、任意の列で並べ替える方法を教えてもらえますか?

アップデート


私の質問は、activerecord クエリを周囲のSELECTandでラップするにはどうすればよいかということだと思いますORDER BY

私はそれを達成することができたと思います:

inner_query = current_user.tasks.select("distinct on (projects.id) projects.*, tasks.*").reorder("projects.id, tasks.milestone ASC").to_sql
@projects = Task.paginate_by_sql("select * from (#{inner_query}) as user_projects order by user_projects.name", :page => params[:page])

それが最善の方法ですか、それとも誰かがより良い方法を考えることができますか? - find/paginate_by_sql は回避策のようで、activerecord クエリの領域内にとどまることをお勧めします。

ありがとう

4

3 に答える 3

2

ユーザーコントローラーで:

inner_query = current_user.tasks.next.to_sql
@projects = Task.paginate_by_sql("select * from (#{inner_query}) as user_projects order by user_projects.#{sort_column} #{sort_direction}", :page => params[:page])

タスクモデルでは:

scope :next, select("distinct on (projects.id) projects.*, tasks.*").reorder("projects.id, tasks.milestone ASC")

この方法では、postgres の機能を使用して必要なレコードのみを返すため、レコードセットが小さくなり、操作が簡単になりますが、トレードオフは、RoR コードが、Carlos Drew の提案ほど魅力的でなく、読みやすいものに見えないことです。

于 2013-07-03T21:11:52.427 に答える