使用active-model-serializers为act-as-taggable标记加载JSON时出错

时间:2013-10-24 11:39:38

标签: ruby-on-rails json acts-as-taggable-on active-model-serializers

在Ruby 2 / Rails 4应用程序中,我尝试将acts-as-taggable-on与active_model_serializers结合使用,以创建一个JSON API,可以输出我的标签以及其他模型参数。

这个问题的第一个背景/动机:JSON正在被提供给ember / ember-data,截至撰写本文时,它已经删除了对JSON中嵌入式记录的支持。 documentation对此有一个假定的修复方法,但我发现它很笨拙,实际上并没有让它起作用。由于我是一个Ember新手并且对Rails感觉更舒服,我想我会尝试以另一种方式解决问题,方法是将标记记录与文档记录一起加载。我更喜欢这个解决方案,因为它对我的应用程序更有意义,但我也无法使用它。

这是一个例子:假设我有一个使用act-as-taggable-on的Document模型:

class Document < ActiveRecord::Base
  acts_as_taggable
  # other code omitted

我用一个带有一个标签的文档设置了数据库。现在我们考虑以下情况:

1。完整对象嵌入:使用以下序列化程序:

class DocumentSerializer < ActiveModel::Serializer
  attributes :id
  has_many :tags

我的JSON具有以下格式(使用Rails 4 UUID):

{
  "documents": [
    {
      "id": "c41460fa-2427-11e3-8702-0800270f33f4",
      "tags": [
        {
          "id": "a33fc396-2428-11e3-8eeb-0800270f33f4",
          "name": "test"
        }
      ]
    }
  ]
}

2。 ID嵌入:使用序列化程序

class DocumentSerializer < ActiveModel::Serializer
  attributes :id
  has_many :tags, embed: :id

我的JSON现在看起来像:

{
  "documents": [
    {
      "id": "c41460fa-2427-11e3-8702-0800270f33f4",
      "tag_ids": [
        "a33fc396-2428-11e3-8eeb-0800270f33f4"
      ]
    }
  ]
}

第3。 ID已嵌入标签Sideloaded :根据active_model_serializers文档,我应该可以做到

class DocumentSerializer < ActiveModel::Serializer
  attributes :id
  has_many :tags, embed: :id, include: true

但这不起作用。相反,我得到一个NoMethodError:

undefined method `object' for #<ActsAsTaggableOn::Tag:0x007f258cf1db38>

我已经尝试过搜索此问题,但到目前为止还没有找到任何有用的内容。我也找不到任何关于使用其他宝石的宝石的文档。我现在怀疑它与如何实现行为标签有关,它不是一个简单的has_many关系?有人能就此问题提供一些意见吗?提前谢谢!

1 个答案:

答案 0 :(得分:11)

固定!结果是侧载标签,必须定义相应的序列化器。我不知道这一点,因为文档似乎暗示让序列化程序是可选的,并且在没有序列化程序的情况下会使用一些默认值。显然,如果您希望使用include: true选项,情况并非如此。关键在于来自here,非常感谢!

为了完整起见,我将展示我的所作所为。我使用以下代码创建了tag_serializer.rb

module ActsAsTaggableOn
  class TagSerializer < ActiveModel::Serializer
    attributes :id, :name
  end
end

现在是我的JSON:

{
   "tags": [
      {
         "id": "a33fc396-2428-11e3-8eeb-0800270f33f4",
         "name": "test"
      }
   ],
   "documents": [
      {
         "id": "c41460fa-2427-11e3-8702-0800270f33f4",
         "tag_ids": [
            "a33fc396-2428-11e3-8eeb-0800270f33f4"
         ]
      }
   ]
}