我正在尝试实现自动完成功能,允许用户从2种不同类型的模型中选择。
这就是我的控制器的外观:
def ac
arr = []
arr << Foo.all
arr << Bar.all
render json: arr.to_json
end
呈现:
[[{"id":1, "name":"foo name"}], [{"id":1, "name":"bar name"}]]
如何包含类名并获取类似内容:
[
[{"id":1, "name":"foo name", "class_name":"Foo"}],
[{"id":1, "name":"bar name", "class_name":"Bar"}]
]
答案 0 :(得分:1)
如果你不介意做一些额外的工作,你可以使用:methods
方法as_json
方法(以及to_json
)来做那样的事情:
class Foo
def class_name
self.class.name
end
end
arr = Foo.all.map { |foo| foo.as_json(:methods => [:class_name]) }
puts arr.to_json
#=> [{ "id": 1, "name": "foo name", "class_name": "Foo" }]
如果您将ActiveRecord::Base.include_root_in_json
设置为true
(默认为afaik),那么您将获得类似
{ "foo": { "id": 1, "name": "foo name" } }
如果您希望它完全是类名,您可以传递:root
选项:
foo = Foo.last
puts foo.to_json(:root => foo.class.name)
#=> { "Foo": { "id": 1, "name": "foo name" } }
请注意,这两种解决方案都不允许您只是在记录数组上调用to_json
。要克服此问题并默认包含class_name
,您可以在模型中覆盖serializable_hash
方法:
def serializable_hash(*)
super.merge('class_name' => self.class.name)
end
如果将其包装到模块中,则可以将其包含在所需的任何模型中,并将class_name
包含在as_json
或to_json
的结果中,而不会向这些方法传递任何额外选项。如果要在某些情况下排除:except
,可以稍微修改实施以尊重class_name
选项。
答案 1 :(得分:0)
最后增加了1个步骤:
arr << Foo.all
arr << Bar.all
arr.flatten!
arr=arr.collect{|itm| {"id":"#{itm.class.to_s}:#{itm.id}", "value":itm.name}}
然后我吐了出来:
render json: arr.to_json()
结果我得到了:
[{"id":"Foo:1", "value":"Foo #1"},{"id":"Bar:1", "value":"Bar #1"}]