【问题标题】:Association's attributes as model's attributes (no nesting) in active model serializers关联的属性作为活动模型序列化器中的模型属性(无嵌套)
【发布时间】:2016-12-19 08:45:33
【问题描述】:

我需要在活动模型序列化器中的 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

【问题讨论】:

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


    【解决方案1】:

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

      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
    

    【讨论】:

    • 谢谢@mat!我的一个朋友提出了同样的想法,但是如果有更多的关联呢?比如belongs_to :class?我必须维护一个 belongs_to 和 has_one 关联名称的数组,并遍历它们以检查并返回值。流程变得复杂。 :-(
    猜你喜欢
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    相关资源
    最近更新 更多