2014-12-30 4 views
7

Я создаю Rest API с помощью rails-api и active-model-serializer, чтобы легко отфильтровать необходимые поля в JSON. Я также использую ассоциацию has_one в этих сериализаторах. Все, что я хотел знать, это как указать другое имя ключа для атрибута has_one.Использование другого имени ключа для атрибута ассоциации в rails api active model serializer

То есть, я две модели говорят: Employee и Address, и есть в has_one :address скажем EmployeeSerializer. Ответ, который я получаю:

{ 
    id: 1, 
    address: { 
    street: "some_street", 
    city: "some_city" 
    } 
} 

Но я хотел бы получить следующий ответ:

{ 
    id: 1, 
    stays: { 
    street: "some_street", 
    city: "some_city" 
    } 
} 

Я попытался с помощью has_one :address, :key => :stays, но это не похоже на работу.

+0

Какую версию AMS вы используете? Я не знаком с базой кода, но из-за быстрого взгляда аргумент 'key', похоже, не был включен во все последние. В качестве обходного пути попробуйте определить 'has_one: остается 'вместе с' def stay; object.address; end'. – janfoeh

+0

@janfoeh Я использую версию 0.9.0.Также я использую другой сериализатор для ассоциации. то есть 'has_one: адрес, ключ: 'статус', serializer: MyAddressSerializer'. Он берет атрибуты из «MyAddressSerializer», но ключ атрибута по-прежнему является «адресом» – swaroopsm

+0

Ah. Если я правильно прочитал [изменения между 0.9.0 и 0.9.1] (https://github.com/rails-api/active_model_serializers/compare/v0.9.0...v0.9.1), аргумент был вызван 'embed_key 'в 0.9.0, а не' key'. – janfoeh

ответ

7

Вы можете определить stays как один из атрибутов, которые вы хотите, чтобы в вашем JSON.

Естественно, сериализатор перейдет к экземпляру модели и не найдет атрибут в модели с этим именем. Таким образом, он будет сидеть там, царапая голову о том, что в мире должно быть значение :stays.

Это нормально, потому что вы можете определить метод экземпляра в своем сериализаторе, указав ему именно то, что должно быть этим значением. В этом случае вам предоставляется переменная object, которая является объектом, который в настоящее время обрабатывает сериализатор. object.address поэтому будет вашим экземпляром Address.

После того, как у вас есть экземпляр вашего адреса, вы можете создать экземпляр сериализатора, который будет использовать этот экземпляр для отображения полей, обозначенных внутри него. Я считаю, что root: false необходимо, так как в противном случае атрибут :stays (или что бы то ни было, в этом случае возвращает сериализатор) будет отображаться внутри другого атрибута :stays.

Ваш окончательный сериализатору для Employee должен выглядеть следующим образом:

class EmployeeSerializer < ActiveModel::Serializer 
    attributes :id, :name, :stays 

    def stays 
    MyAddressSerializer.new(object.address, root: false) 
    end 

end 
+0

Добавьте описание, почему он будет выполнять эту работу. сам по себе. Он очень низкого качества и не очень хорошо подходит для стиля SO Q & A и был отмечен как сообщение низкого качества. – Cheesebaron

+0

@ Cheesebaron как это? :) – Kalman

+0

намного лучше :) – Cheesebaron

3

@janfoeh прямо на. Я только проверил это в версии 0.8, и она работает просто отлично

  1. gem "active_model_serializers", "~> 0.8.0" в вашем Gemfile
  2. убить сервер
  3. $bundle install
  4. has_one :address, key: "stays"
  5. запустить сервер резервного копирования

Прекрасно работает!

В документации на драгоценный камень говорит (here), «вы, вероятно, хотите использовать версию 0.8»

+0

Если я использую версию '0.8.0',' MyAddressSerializer' не работает: 'has_one: адрес, ключ: 'статус', сериализатор: MyAddressSerializer' – swaroopsm

+0

@swaroopsm is «Адрес» всегда сериализуется с помощью «MyAddressSerializer»? Если да, вы можете определить, что на самом «Адресе» с 'def active_model_serializer; MyAddressSerializer; end'. – janfoeh

 Смежные вопросы

  • Нет связанных вопросов^_^