关联的属性作为活动模型序列化程序中的模型属性(无嵌套)

时间:2016-12-19 08:45:33

标签: ruby-on-rails ruby-on-rails-4 active-model-serializers

我需要在活动模型序列化程序中使用belongs_to和has_one关联的属性作为关联名称的前缀,并将其序列化为模型的直接属性。我不希望它们嵌套, 在模型下,但它在同一水平上持平。

例如,

class StudentSerializer
  attributes :name, :email
  belongs_to :school
end

class SchoolSerializer
  attributes :name, :location
end

对于上面的串行器,输出将是

{
  id: 1,
  name: 'John',
  email: 'mail@example.com',
  school: {
   id: 1,
   name: 'ABC School',
   location: 'US'
  }
}

但我需要它,

{
  id: 1,
  name: 'John',
  email: 'mail@example.com',
  school_id: 1,
  school_name: 'ABC School',
  school_location: 'US'
}

我可以通过将以下方法添加到序列化程序(如

)来实现
attributes :school_id, :school_name, :school_location  

def school_name
  object.school.name
end

def school_location
  object.school.location
end

但我不认为这是一个很棒的'因为我需要为关联中的所有属性定义方法。任何想法或解决方法(或直接解决方案,如果我都缺少),以实现这一优雅? TIA。

更新: 我现在暂时处理了每个协会的以下解决方法。

attributes :school_name, :school_location

[:name, :location].each do |attr|
  define_method %(school_#{attr}) do
    object.school.send(attr)
  end
end

1 个答案:

答案 0 :(得分:0)

您可以将虚拟属性作为缺少的方法进行管理:

  attributes :school_id, :school_name, :school_location 

  def method_missing( name, *_args, &_block )
    method = name.to_s
    if method.start_with?( 'school_' )
      method.slice! 'school_'
      object.school.send( method )
    end
  end

  def respond_to_missing?( name, include_all = false )
    return true if name.to_s.start_with?( 'school_' )
    super
  end