我有两个模型:项目和待办事项。在项目索引中,我想显示项目的概述,包括项目名称和项目中待办事项的数量,状态为“do”,“doing”或“done”。 (例如:做:12 |做:2 |完成:25)。在我的项目控制器中,我可以检索所有项目,但我还需要找出每个项目中涉及每种状态的待办事项数量。我已通过在项目索引视图中定义其他数据库查询来解决此问题:
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
答案 0 :(得分: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
答案 1 :(得分: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
project.todos.do.count
project.todos.doing.count...
答案 2 :(得分: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