在我的模型中,我有一个as_json方法,如下所示:
def as_json(options = {})
super(options.merge(include: [:user, comments: {include: :user}]))
end
此方法用于在评论中包含用户。
现在我需要在同一模型中添加几乎相同的东西以获得答案:
def as_json(options = {})
super(options.merge(include: [:user, answers: {include: :user}]))
end
如何组合这两个as_json方法,以便我有一个as_json方法?
不要笑,但是我在为此奋斗了3天。答案 0 :(得分:3)
这是您不应使用内置to_json
序列化ActiveRecord模型的原因之一。
相反,您应该将任务委托给另一个名为serializer的对象。使用序列化程序可以让您拥有同一对象的 illimitate Representations (序列化)(如果对象可以有不同的变体,例如有/没有注释等,则非常有用)和关注点分离强>
创建自己的序列化程序很简单,就像拥有
一样简单class ModelWithCommentsSerializer
def initialize(object)
@object = object
end
def as_json
@object.as_json(include: [:user, comments: {include: :user}]))
end
end
class ModelWithAnswersSerializer
def initialize(object)
@object = object
end
def as_json
@object.as_json(include: [:user, answers: {include: :user}]))
end
end
当然,这仅仅是一个例子。您可以提取该功能以避免重复。
还有一些像ActiveModelSerializers
这样的宝石提供了这个功能,但是我更愿意避免它们,因为它们往往提供了大部分用户真正需要的东西。
答案 1 :(得分:0)
def as_json(other_arg, options = {})
as_json(options.merge(include: [:user, other_arg: {include: :user}]))
end
然后你可以打电话:
MyModel.as_json(:comments)
MyModel.as_json(:answers)
答案 2 :(得分:0)
为什么要尝试覆盖核心Rails功能 - 除非绝对必要,否则不是好的做法。
-
This说以下内容:
要包含关联,请使用:include:
user.as_json(include: :posts)
# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
# "created_at" => "2006/08/01", "awesome" => true,
# "posts" => [ { "id" => 1, "author_id" => 1, "title" => "Welcome to the weblog" },
# { "id" => 2, "author_id" => 1, "title" => "So I was thinking" } ] }
你可以打电话:
@answers.as_json(include :users)
-
Ohhhhhhhh:
二级和更高级别的关联也起作用:
user.as_json(include: { posts: {
include: { comments: {
only: :body } },
only: :title } })
# => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
# "created_at" => "2006/08/01", "awesome" => true,
# "posts" => [ { "comments" => [ { "body" => "1st post!" }, { "body" => "Second!" } ],
# "title" => "Welcome to the weblog" },
# { "comments" => [ { "body" => "Don't think too hard" } ],
# "title" => "So I was thinking" } ] }
所以看起来你可以打电话:
@answers.to_json(include: comments: { include: :users })