Ruby on Rails API:计算属性模式最佳实践

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)

spi*_*ann 5

在这种情况下,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_countParent类中删除自定义方法,并且仍然可以简单地调用

<%= 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)