3

私のレール4プロジェクトでは、次のテーブルがあります ここに画像の説明を入力

このSO questionでは、SQL クエリを検索して、実際のプロジェクト ステータス ID = XXのプロジェクトを取得しました。実際には、max(created_at) を持つものを意味します。

私は私の質問に対する答えを得ました

select p.* from projects p
     left join projects_status_projects psp on (psp.project_id = p.id)
     where created_at = (select max(created_at) from projects_status_projects 
           where project_id = p.id)    
     and project_status_id = XX

私のモデルは定義されています

class Project < ActiveRecord::Base
   has_many :projects_status_projects
   has_many :projects_statuses, :through => :projects_status_projects
end

class ProjectStatus < ActiveRecord::Base
   has_many :projects_status_projects
   has_many :projects, :through => :projects_status_projects
end

class ProjectsStatusType < ActiveRecord::Base
   belongs_to :project
   belongs_to :project_status
end

私のプロジェクトモデルには、次のメソッドがあります

def self.with_status(status)
   joins(:projects_status_projects)
       .where('projects_status_projects.created_at = (select max(created_at) from 
                    projects_status_projects where project_id = p.id)')
       .where('projects_status_projects.project_status_id = ?', status)
end

クエリは正しいですが、受信した結果は適切にフィルタリングされていますが、このソリューションはひどいものであり、まったくエレガントではありません。

スコープで同じ結果を得る方法はありますか?

ご協力いただきありがとうございます。

4

3 に答える 3

1

どう思いますか

scope :with_status, -> (status) { 
   ProjectsStatusType.where(:project_status_id, status).order(:created_at).last.project 
}

コメントに基づく編集:

sockmonk が言ったように、スコープは連鎖可能であるべきです。これは、プロジェクトが見つからない場合に問題を解決する、よりクリーンな方法です。

# ProjectStatusType model
scope :with_ordered_status, -> (status) { 
   where(:project_status_id, status).order(:created_at)
}

# Project model
def self.find_by_status(status)
  project_statuses = ProjectsStatusType.with_ordered_status(status)
  project_statuses.any? ? project_statuses.last.project : nil
end
于 2013-10-08T15:50:04.920 に答える
0
scope :with_status, ->(status = "default_status") {
  joins(:projects_status_projects)
  .where('projects_status_projects.project_status_id = ?', status)
  .order("projects_status_projects.created_at DESC")    
}

呼び出すときは、末尾に「.first」を追加します。スコープ自体に .first を含めることはできません。

于 2013-10-08T15:52:27.677 に答える