Alp*_*a60 3 design-patterns ruby-on-rails ruby-on-rails-6
当我需要需要调用数据库的计算属性时,我想知道最佳实践。
如果我有一个Parent有 many Child,我将如何渲染一个children_count属性,ParentController#index因为我不想渲染孩子,只是计数?最好的方法是什么?
谢谢!
模型:
class Parent < ApplicationRecord
has_many :children
def children_count
children.count # Wouldn't it ask the database when I call this method?
end
end
Run Code Online (Sandbox Code Playgroud)
控制器:
class ParentsController < ApplicationController
def index
parents = Parent.all
render json: parents, only: %i[attr1, attr2] # How do I pass children_count?
end
end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Rails 避免额外数据库查询的方法是实现计数器缓存。
这样做改变
belongs_to :parent
Run Code Online (Sandbox Code Playgroud)
在child.rb以
belongs_to :parent, counter_cache: true
Run Code Online (Sandbox Code Playgroud)
children_count并向您的parents数据库表中添加一个名为的整数列。当您的数据库中已经有记录时,您应该运行类似
Parent.ids.each { |id| Parent.reset_counters(id) }
Run Code Online (Sandbox Code Playgroud)
children_count用正确数量的现有记录填充(例如在您添加新列的迁移中)。
完成这些准备工作后,Rails 会在您添加或删除子项时自动增加和减少计数。
因为children_count数据库列的处理方式与所有其他属性一样,所以您必须children_count从Parent类中删除自定义方法,并且仍然可以简单地调用
<%= parent.children_count %>
Run Code Online (Sandbox Code Playgroud)
在你看来。或者,您可以将其添加到要作为 JSON 返回的属性列表中:
render json: parents, only: %i[attr1 attr2 children_count]
Run Code Online (Sandbox Code Playgroud)