Активная ассоциация сериализатора модели, если только object.user == current_user

У меня есть модель пользователя и модель занятости, например:

Class User
 has_many :employments

Class Employment
 belongs_to :user

Я отправляю JSON API через активный сериализатор модели следующим образом:

class EmploymentSerializer < ActiveModel::Serializer
  attributes :id
  has_one :user

class UserSerializer < ActiveModel::Serializer
  attributes :id

Все работает как надо. Вот проблема:

Когда current_user является работодателем, я бы загружал рабочие места с ассоциациями пользователей, которые отлично работают. Когда current_user не является работодателем, я хочу загрузить рабочие места, принадлежащие пользователю.

Поскольку EmploymentSerializer has_one :user, это приводит к рекурсивному запросу, в котором current_user has_one занятости has_one current_user до бесконечности.

Я попытался добавить этот метод в EmploymentSerializer, но он не работает:

def include_user?
  object.user != scope
end

Как мне загрузить рабочие места current_user?


Решение

Рекурсию вызвал другой сериализатор, и этот вопрос неактуален. АМС работает как надо.


person Ryan.lay    schedule 05.05.2015    source источник


Ответы (1)


С belongs_to таблица берет на себя ответственность за внешний ключ. С has_one таблица ожидает, что другая таблица удержит ее. Поскольку ваша таблица Employments имеет внешний ключ для таблицы Users, has_one :user в сериализаторе не имеет смысла, поскольку предполагается, что таблица Users имеет внешний ключ для таблицы Employments.

Как правило, отношения сериализатора обычно должны отражать модель, и вы смешиваете их здесь. Когда ваш класс Employment имеет отношение belongs_to :user, ваш сериализатор должен иметь такое же отношение, а не противоположное отношение has_one.

Редактировать: комментарий Ryan.lee верен. В active_model_serializers has_one действительно совпадает с belongs_to, потому что сериализаторы заботятся о множественности, а теперь и о владении. Но так как это довольно запутанно, потому что ActiveRecord, версия 0.9 также добавляет поддержку belongs_to, чтобы отразить ассоциации ActiveRecord. Таким образом, использование has_one в сериализаторе, когда модель имеет belongs_to, действительно правильно, но я бы предложил также использовать belongs_to в сериализаторе, чтобы избежать путаницы, поскольку они означает одно и то же в контексте сериализатора (но не ActiveRecord!)

person p4sh4    schedule 05.05.2015
comment
AMS has_one указывает на множественность, а не на принадлежность. Он просто сообщает AMS, какие записи нужно извлечь. Это не то же самое, что отношение Activerecord has_one. - person Ryan.lay; 05.05.2015
comment
Какую версию AMS вы используете? - person p4sh4; 05.05.2015
comment
0.10.0.rc1. Как оказалось, рекурсия была вызвана другим сериализатором, поэтому я удалю этот вопрос. Спасибо за попытку помочь! - person Ryan.lay; 05.05.2015