最近在给 iphone 做接口,用 grape,打算跟 web 项目在同一个项目目录,并打算共用 model,所以选用了 grape,但是涉及到了自定义 json 数据格式的问题,前些天有问群里的大牛们,给出的方法我都试过了,并且读了下 ruby-china 的客户端 api,见到了有类似的写法:
get do
@topics = Topic.last_actived
.limit(page_size)
.includes(:user)
present @topics, :with => APIEntities::Topic
end
这其中用到了 APIEntities::Topic,再进入到里面看个究竟,是这样的代码:
module RubyChina
module APIEntities
class User < Grape::Entity
expose :_id, :name, :login, :location, :website, :bio, :tagline, :github_url
expose(:gravatar_hash) { |model, opts| Digest::MD5.hexdigest(model.email || "") }
expose(:avatar_url) { |model, opts| model.avatar? ? model.avatar.url(:normal) : "" }
end
class Reply < Grape::Entity
expose :_id, :body, :body_html, :message_id, :created_at, :updated_at
expose :user, :using => APIEntities::User
end
class Topic < Grape::Entity
expose :_id, :title, :body, :body_html, :created_at, :updated_at, :replied_at, :replies_count, :node_name, :node_id, :last_reply_user_login
expose :user, :using => APIEntities::User
# replies only exposed when a single topic is fetched
expose :replies, :using => APIEntities::Reply, :unless => { :collection => true }
end
class Node < Grape::Entity
expose :_id, :name, :topics_count, :summary, :section_id, :sort
expose(:section_name) {|model, opts| model.section.name.to_s rescue "" }
end
end
end
于是乎,我就照着写了一个类似的
resource :rooms do
get '/' do
@rooms = Room.limit 30
present @rooms, :with => APIEntities::Room
end
end
以及
module APIEntities
class Room < Grape::Entity
expose :id, :title, :custom_num, :home_type
expose(:address) { |model, opts| model.address_info }
expose(:price) { |model, opts| model.price.try(:day_price) }
expose(:first_screen) { |model, opts| model.first_screen(:icon) }
end
end
然后我重启 server 访问: localhost:3000/api/v1/rooms 得到了以下数据:
[
{
home_type: "1",
id: 842,
address: "唐山市xxxxx",
custom_num: 4,
price: 100,
title: "精装单间",
first_screen: "/uploads/screenshot/photo/000/312/icon_aeb963221fb8478e75df3ef480dae4c2.gif"
},
{
id: 843,
home_type: "1",
address: "上海市松江区新桥镇",
custom_num: 4,
price: 100,
title: "精装单间",
first_screen: "/uploads/screenshot/photo/000/307/icon_e3b5c399f052afaed6a14f85eee5ce12.gif"
},
{
home_type: "公寓",
id: 858,
address: "鄂尔多斯市伊金霍洛旗乌兰木伦镇",
custom_num: 1,
price: 100,
title: "精装单间",
first_screen: "/uploads/screenshot/photo/000/000/153/icon_1.jpg"
}
]
这样的数据我基本上是我想要的,因为我都为 room 对象添加了虚拟属性,解决了子父关联关系的问题。但是我还是想加一个 status,标识返回的数据状态,类似与这样:
{"status":"OK",
{"siteId":"siteId1","siteUrl":"www.site1.300.cn","siteName":"siteName1"},
{"siteId":"siteId2","siteUrl":"www.site2.300.cn","siteName":"siteName2"}
}
其实就是想在现有的数据的基础上加一个 status,不知道想要得到这样的结果,利用 Grape::Entity 能否实现,昨天我看了看 api 没有找到合适的方法,如果有哪位大牛对 grape 很熟悉的话,希望大家能给个建议,谢谢。