Rails 7中如何在Product查询结果中关联加载Category名称?
解决方法:将分类名称嵌入Product输出结果
1. 用as_json自定义JSON输出(最直接)
includes(:category)的作用是预加载关联数据避免N+1查询,但它不会改变inspect的输出(inspect只显示模型的数据库字段)。要给JS传递包含分类名称的数据,直接在输出时用as_json定制结构:
在控制器的index方法里:
def index @products = Product.includes(:category).all # 渲染包含分类名称的JSON render json: @products.as_json(include: { category: { only: :name } }) end
这样返回的JSON中,每个product对象会嵌套一个category对象,里面只包含name字段,JS可以直接读取product.category.name。
如果不想嵌套,也可以把分类名称平级放在product里:
def index @products = Product.includes(:category).all products_data = @products.map do |p| p.as_json.merge(category_name: p.category&.name) end render json: products_data end
2. 在Product模型中添加辅助方法
在app/models/product.rb里新增一个方法:
def category_name category&.name # 用&.避免category为nil时出错 end
然后在输出时把这个方法的结果包含进去:
def index @products = Product.includes(:category).all render json: @products.as_json(methods: :category_name) end
这样返回的JSON每个product会多一个category_name字段,直接对应分类名称。
补充:关于includes的说明
你之前用Product.includes(:category).all是正确的,它已经把所有product对应的category数据一次性加载好了,不会在调用product.category时触发额外SQL。只是inspect方法默认只显示模型的数据库字段(比如category_id),不会展示关联对象的内容,所以看起来好像没加载,但实际上关联数据已经在内存里了。
内容的提问来源于stack exchange,提问作者Vecot
相关产品推荐
相关产品推荐

