Rails 请教一个写 API 时遇到的问题

shin · 2016年06月11日 · 最后由 shin 回复于 2016年06月13日 · 2686 次阅读

我用 active_model_serializers;有 3 个类

class UserSerializer < ActiveModel::Serializer
  attributes :id, :username, :email, :authentication_token

  has_many :posts
  has_one :profile
end
class ProfileSerializer < ActiveModel::Serializer
  attributes :name, :bio, :avatar

  belongs_to :user_id
end
class PostSerializer < ActiveModel::Serializer
  attributes :id, :content, :video

  belongs_to :user
end

我在 api/v1/posts.json 下可以列出 post 数据和 user 数据,那在移动端就可以 Get 和 initialize 数据,我希望能在 api/v1/posts.json 下也能列出 profile 的数据,这样在移动端的页面可以显示每篇 post 的内容和用户名,用户头像;(这因该是在服务器端把数据都列出来,还是在移动端根据 user_id 查询 profile 数据?)

class Api::V1::PostsController < Api::V1::BaseController
    load_and_authorize_resource except: [:index, :show]

    def index
        posts = Post.all
        paginate json: posts, per_page: 2, status: 200
    end
[{"id":309,"content":"test","video":{"video":{"url":"http://test.7xo9gv.com1.z0.glb.clouddn.com/uploads/tumblr_nu7jc4y4sI1udfmeqo1_500.gif?e=1465652771\u0026token=VVHcT1wQxm_qS45p-4s2TEM7dtDlWk-yTMrC_eu5:v87uXlAjiQrCKe-kHDaPB7Dxp5="}},"user_id":1,"user":{"id":1,"username":"shin","email":"shin@gmail.com","authentication_token":"S_apCGF3wodNtKzWkeGYtYZ3dJxFPX-8"}}

这样

def index
    posts = Post.all
    paginate json: posts, include: { user: :profile }, per_page: 2, status: 200
end

active_model_serializers 的 0.10 版本改动好大,文档都不知道移到哪里去了。。

@ericguo cool 可以啊~你在文档哪里找到有这样写法的?谢谢!

#2 楼 @shin 翻 issue,竟然可以用?其实我也没试过。。

在对应的 model 里 overwrite as_json这个方法。

然后你可以对应 index 和 show 渲染不同的 json data。

比如下面这个代码示例

def as_json(options={})
    if options[:action] == :index
      super(
        {
          except: [:created_at, :updated_at],
          include: {
            address: { except: [:id, :venue_id, :created_at, :updated_at, :bearing] } 
          }
        }
      )
    elsif options[:action] == :show
      super(
        {
          except: [:created_at, :updated_at],
          include: {
            address: { except: [:id, :venue_id, :created_at, :updated_at, :bearing] }, 
            courts: {
              except: [:created_at, :updated_at, :venue_id],
              methods: [ :timetable ]
            } 
          }
        }
      )
    end
  end

controller 里你可以就这样:

def show
    render json: @venue, action: :show
  end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号