RABL - 子节点内的属性

时间:2012-09-05 17:14:53

标签: ruby-on-rails ruby json rabl

如果我使用node()方法在RABL中创建子节点,我该如何控制显示的属性?

JSON输出是这样的:

[
    {
        "location": {
            "latitude": 33333,
            "longitude": 44444,
            "address": "xxxxxxx",
            "title": "yyyy",
            "url": "http://www.google.com",
            "rate": {
                "created_at": "2012-09-02T11:13:13Z",
                "id": 1,
                "location_id": 1,
                "pair": "zzzzzz",
                "updated_at": "2012-09-02T12:55:28Z",
                "value": 1.5643
            }
        }
    }
]

我想摆脱created_at,updated_at和location_id属性。

我在我的视图文件中有这个:

collection @locations
attributes :latitude, :longitude, :address, :title, :url
node (:rate) do   
  |location| location.rates.where(:pair => @pair).first
end

我尝试使用部分和'扩展'方法,但它完全搞砸了。此外,我尝试向块添加属性但它不起作用(输出是在属性中指定的,但它没有显示每个属性的值)。

谢谢!

2 个答案:

答案 0 :(得分:2)

您将无法在节点块中使用attributes,因为其中的“self”仍然是根对象或集合,因此在您的情况下@locations。另请参阅RABL wiki: Tips and tricks (When to use Child and Node)

在节点块中,您只需列出您感兴趣的属性即可创建自定义响应:

node :rate do |location|
  rate = location.rates.where(:pair => @pair).first
  {:id => rate.id, :location_id => rate.location_id, :value => rate.value}
end

您也可以尝试使用部分方法:

app/views/rates/show.json.rabl

object @rate
attributes :id, :location_id, :value

然后在你的@locations rabl视图中:

node :rate do |location|
  rate = location.rates.where(:pair => @pair).first
  partial("rates/show", :object => rate)
end

答案 1 :(得分:2)

您的代码:location.rates.where(:pair => @pair).first返回整个Rate对象。如果你想要特定的字段(例如:all,除了create_at,updated_at等),你有两个选择:

手动描述node()中的哈希:

node (:rate) do |location|  
   loc = location.rates.where(:pair => @pair).first
   { :pair => loc.pair, :value => loc.value, etc... }
end

或者你可以这个

node (:rate) do |location|  
   location.rates.where(:pair => @pair).select('pair, value, etc...').first
end

...作为旁注,我应该说在您的视图中放置逻辑(rates.where)并不是最佳做法。看看您的控制器是否可以使用Rate模型为视图执行此操作。