0

プロジェクトと todos の 2 つのモデルがあります。プロジェクト インデックスでは、プロジェクトの概要を、プロジェクト名と、プロジェクト内の「実行中」、「実行中」、または「完了」ステータスの Todo アイテムの数で構成して表示したいと考えています。(例: do:12 | doing:2 | done:25 )。私のプロジェクト コントローラーでは、すべてのプロジェクトを取得できますが、さらに、各プロジェクトに関連する各ステータスの Todo アイテムの数を調べる必要があります。プロジェクト インデックス ビューで追加のデータベース クエリを定義することで、これを修正しました。

Todo.where("project_id = ?", project.id).where("status = ?", "done").count)

これは、これを解決する正しい (MVC) 方法ではないようです。より良い方法は何でしょうか?結果のコレクションのサブセットに対して追加のクエリを実行するにはどうすればよいですか?

以下に関連するすべてのコードを含めようとしました。

class Project < ActiveRecord::Base
has_many :todos,  dependent: :destroy
end


class Todo < ActiveRecord::Base
acts_as_list
belongs_to :project
end

モデルのスキーマは次のとおりです。

create_table "projects", force: true do |t|
   t.string   "name"
   t.datetime "created_at"
   t.datetime "updated_at"
 end

 create_table "todos", force: true do |t|
   t.string   "name"
   t.string   "description"
   t.string   "status"
   t.datetime "created_at"
   t.datetime "updated_at"
   t.integer  "position"
   t.integer  "project_id"
  end

プロジェクト コントローラー:

class ProjectsController < ApplicationController
  before_action :set_project, only: [:show, :edit, :update, :destroy]

  def index
   @projects = Project.all

  end
4

3 に答える 3

1

よりクリーンな方法は、スコープを作成することです

class Todo < ActiveRecord::Base
acts_as_list
belongs_to :project
scope :do, -> { where(status: 'do') }
scope :doing, -> { where(status: 'doing') }
scope :done, -> { where(status: 'done') }
end

そしてプロジェクトから

project.todos.do.count
project.todos.doing.count...
于 2013-11-12T09:23:37.747 に答える
1

カウンターには追加の列を使用したいと思います。

create_table "projects", force: true do |t|
   t.string   "name"
   t.datetime "created_at"
   t.datetime "updated_at"
   t.integer "doing_counter"
   t.integer "done_counter"
 end

その後、Todo モデルでコールバック、after_save、after_destroy を使用します。

class Todo < ActiveRecord::Base
  acts_as_list
  belongs_to :project
  after_save :update_counters
  after_destroy :update_counters
  def update_counters
       self.project.update_attribute(:doing_counter, self.project.todos.where('status=?', 'doing').count)
       self.project.update_attribute(:done_counter, self.project.todos.where('status=?', 'done').count)
  end
end

== パフォーマンス調整

class Todo < ActiveRecord::Base
  acts_as_list
  belongs_to :project
  after_create :update_counters
  after_update :update_counters_if_changed
  after_destroy :update_counters

  def update_counters_if_changed
       update_counters if status_changed?
  end

  def update_counters
       self.project.update_attribute(:doing_counter, self.project.todos.where('status=?', 'doing').count)
       self.project.update_attribute(:done_counter, self.project.todos.where('status=?', 'done').count)
  end
end
于 2013-11-12T09:18:37.993 に答える
0

あなたのprojectモデルでこのようなことを試すことができます

def todo_count(type)
  #get todos of a given status
  todo = self.todos.where("status = ?", type.to_s)
  #count them
  todo.count
end

次のようにビューで呼び出します。

<%= @project.todo_count(do) %> #to get the count of `do` items
于 2013-11-12T09:17:06.910 に答える