如何解决Ruby on Rails API:计算属性模式最佳实践
当我需要一个需要调用数据库的计算属性时,我想了解最佳实践。
如果我有一个Parent
,其中有许多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
控制器:
class ParentsController < ApplicationController
def index
parents = Parent.all
render json: parents,only: %i[attr1,attr2] # How do I pass children_count?
end
end
解决方法
在这种情况下,避免其他数据库查询的Rails方法是实现counter cache。
为此进行更改
belongs_to :parent
在child.rb
至
belongs_to :parent,counter_cache: true
并将一个名为children_count
的整数列添加到您的parents
数据库表中。如果数据库中已经有记录,则应该运行类似的
Parent.ids.each { |id| Parent.reset_counters(id) }
用正确数量的现有记录填充children_count
(例如,在您添加新列的迁移中)。
这些准备工作完成后,Rails将在添加或删除子项时自动处理计数的递增和递减。
由于children_count
数据库列的处理方式与所有其他属性一样,因此必须从children_count
类中删除自定义Parent
方法,并且仍然可以简单地调用
<%= parent.children_count %>
在您看来。或者,您可以将其添加到要作为JSON返回的属性列表中:
render json: parents,only: %i[attr1 attr2 children_count]
,
children.count
将调用数据库,是的;但是,它将作为SQL计数来完成:
SELECT COUNT(*) FROM "children" WHERE "children"."parent_id" = $1
它实际上并不会加载所有子记录。对于这种特定情况,更有效的方法是使用Rails counter_cache:https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-counter-cache
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。