ActiveModel :: Serializers JSON API嵌套关联包括?

时间:2017-05-31 09:43:56

标签: ruby-on-rails active-model-serializers json-api

我还没有在Stackoverflow上找到完全相同的问题。除了AMS变化如此之快,即使是2年的答案也经常过时。

我只使用Rails 5 API和gem' active_model_serializers' (AMS)(版本0.10.6)。

我也使用JSONAPI响应格式 - 而不仅仅是JSON。

我需要渲染嵌套包含 - 而不仅仅是现在的嵌套关系。

代码示例:

serializer1:

class QuestionSerializer < ActiveModel::Serializer
  attributes :id, :title, :created_at, :updated_at
  belongs_to :user
end

serializer2:

class UserSerializer < ActiveModel::Serializer
  attributes :id, :email
  has_many :cities
end

serializer3:

class CitySerializer < ActiveModel::Serializer
  attributes :id, :name
end

控制器:

def index
  @questions = Question.all
  render json: @questions, include: [:user, 'user.city']
end

我收到了这个回复:

{
  "data": [
    {
      "id": "1",
      "type": "questions",
      "attributes": {
        "title": "First",
        "created-at": "2017-03-27T13:22:15.548Z",
        "updated-at": "2017-03-27T13:22:16.463Z"
      },
      "relationships": {
        "user": {
          "data": {
            "id": "3",
            "type": "users"
          }
        }
      }
    }
  ],
  "included": [
    {
      "id": "3",
      "type": "users",
      "attributes": {
        "email": "client2@example.com"   
      },
      "relationships": {
        "cities": {
          "data": [
            {
              "id": "75",
              "type": "cities"
            }
          ]
        }
      }
    }
  ]
}

我确实得到了嵌套关系city。我甚至得到了城市id

但问题是 - 如何获得city之类的其他name属性?我需要另一个include部分 - 可能在当前include部分内(嵌套?)。

怎么做? (没有任何额外的宝石)

3 个答案:

答案 0 :(得分:1)

我找到了一些解决方案。我不知道它有多干净。它基于2个先决条件:

  1. https://github.com/rails-api/active_model_serializers/blob/db6083af2fb9932f9e8591e1d964f1787aacdb37/docs/general/adapters.md#included

  2. ActiveModel Serializers: has_many with condition at run-time?

  3. 我应用了条件关系和user - 所有宽容include

    控制器:

    @questions = Question.all
    
    render json: @questions,
    
    show_user: (param? params[:user]),
    
    show_cities: (param? params[:city]),
    
    include: [:user, "user.**"]
    

    serializer1:

    class QuestionSerializer < ActiveModel::Serializer
      attributes :id, :title, :created_at, :updated_at
      belongs_to :user, if: -> { should_render_user }
    
      def should_render_user
        @instance_options[:show_user]
      end   
    end
    

    serializer2:

    class UserSerializer < ActiveModel::Serializer
      attributes :id, :email
      has_many :cities, if: -> { should_render_cities }
    
      def should_render_cities
        @instance_options[:show_cities]
      end    
    end
    

    serializer3:

    class CitySerializer < ActiveModel::Serializer
      attributes :id, :name
    end
    

    助手:

    def param? param
    
      param && param != "false" && param != "nil"
    
    end
    

    条件关系允许控制实际呈现的include

答案 1 :(得分:0)

以下应该这样做

render json: @questions, include: [:categories, user: :city]

答案 2 :(得分:0)

您还应该将用户包含在参数&#39;字段&#39;并使用字符串而不是符号作为参数include

%MACRO J;
    %DO I=1 %TO 2;
        %put FTP.TOTAL_4B_%sysfunc(intnx(DAY,%sysfunc(today()),-&I.,S),yymmddn8.);
    %END;   
%MEND J;
%J;