我知道如何全局禁用根元素,la Rails 3.1 include_root_in_json或使用ActiveRecord::Base.include_root_in_json = false
,但我只想为少数JSON请求(不是全局)执行此操作。
到目前为止,我一直在这样做:
@donuts = Donut.where(:jelly => true)
@coffees = Coffee.all
@breakfast_sandwiches = Sandwich.where(:breakfast => true)
dunkin_donuts_order = {}
dunkin_donuts_order[:donuts] = @donuts
dunkin_donuts_order[:libations] = @coffees
dunkin_donuts_order[:non_donut_food] = @breakfast_sandwiches
Donut.include_root_in_json = false
Coffee.include_root_in_json = false
render :json => dunkin_donuts_order
Donut.include_root_in_json = true
Coffee.include_root_in_json = true
大约有5个案例我必须这样做,有时会有多个型号,而且根本不觉得干净。我曾尝试将其放在around_filter
中,但例外情况正在打破流量,而且这也变得毛茸茸。
必须有更好的方法!
答案 0 :(得分:2)
不幸的是,答案是肯定的,不是。
是的,你上面所做的事情可以说是更好。不,Rails不会让你在每个动作的基础上添加root。 JSON渲染并没有考虑到这种灵活性。
话虽如此,这就是我要做的事情:
include_root_in_json
设置为false
以获取具有root权限的模型,具体取决于操作(例如上面的Donut
和Coffee
)。覆盖as_json
以提高灵活性。这是一个例子:
# in model.rb
def as_json(options = nil)
hash = serializable_hash(options)
if options && options[:root]
hash = { options[:root] => hash }
else
hash = hash
end
end
此示例将使您可以选择传递根,但默认为无根。你也可以用另一种方式写它。
as_json
,因此您必须适当地修改渲染调用。因此,对于Donut
,您需要render :json => @donut.to_json
。希望这有帮助!
答案 1 :(得分:1)
您可以为每个模型实例设置include_root_in_json
,它不会影响该类(有关此行为的说明,请参阅rails api中的class_attribute
)。因此,您可以在类级别设置合理的默认值,然后在相关控制器中的每个实例上设置不同的值。
示例:
@donuts = Donut.where(:jelly => true).each {|d| d.include_root_in_json = false }
为方便起见,您可以创建一个实用程序方法,该方法接受一组模型实例并在所有模型实例上设置值。