我有两个班叫教室和学生。他们有一种多对多的关系,因为教室可以有许多学生,但学生也可以属于许多教室。当我调用api来获取一个部分教室时,我还想抓取属于该教室的所有学生(通过Student教室联接表),并将他们添加到我从api返回的教室activerecord对象中。
如果我在控制器中返回响应之前使用binding.pry i暂停执行,@教室.students将按预期返回一组学生记录。然而,当@教室被发送到前端时,它将从学生数组中剥离。我做错了什么?
课堂
class Classroom < ApplicationRecord
has_many :student_classrooms
has_many :students, through: :student_classrooms
def get_classroom_students(classroom_id)
StudentClassroom.where(classroom_id: classroom_id)
end
end
控制器
def show
students = @Classroom.get_classroom_students(@Classroom.id)
# somehow add students to @Classroom ActiveRecord object
render json: @Classroom
end
2条答案
按热度按时间sqserrrh1#
这永远不会让学生回到前端。当你添加
binding.pry
在控制器上测试,你仍然有ActiveRecord
具有students
方法已定义,但将其传递到前端时,会将其转换为json:所以json没有学生数组。要解决此问题,您可以在show action上尝试以下操作:
这将包括
students
在json中,您将传递到前端。如果您希望将此行为设置为默认行为,即
Classroom
对象转换为json,然后包含students
你可以加上as_json
方法论Classroom
像这样的课程:现在,每当
Classroom
对象转换为json,它将包括学生。示例:mqxuamgl2#
当你打电话的时候
render
没有神奇的事情发生:在响应体中发送之前,您的课堂对象将被序列化。ar模型的默认json序列化大致上是属性的散列-没有关联,没有示例方法等。您可以通过重新定义
as_json
对于模型,正如另一个答案所建议的,但这通常是一个坏主意-对于不同的端点和/或场景,您可能(而且很可能会)需要不同的序列化,因此在模型中只使用一个硬编码将迫使您添加越来越多的黑客攻击。更好的方法是将序列化与业务逻辑解耦——这就是序列化程序发挥作用的地方。看看https://github.com/jsonapi-serializer/jsonapi-serializer 例如,这就是您需要以干净且可维护的方式解决任务的原因。
只需定义一个序列化程序
(只是一个草稿-请参阅文档以释放所有的力量:))您可以使用以下简单的方法: