Rails accept_nested_attributes создает новый ресурс с определенным идентификатором - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть входящий SOAP-запрос, который пытается создать или обновить вложенные ресурсы. Входящие ресурсы уже имеют идентификатор, который я хотел бы использовать как свой собственный, вместо создания нового. Прежде чем идти дальше, позвольте мне представить вам некоторый контекст.

У меня есть следующие модели:

class AccountedTime < ApplicationRecord
  belongs_to :article, optional: false
end

class Article < ApplicationRecord
  has_many :accounted_times, dependent: :destroy
  accepts_nested_attributes_for :accounted_times, allow_destroy: true
end

Проблема, с которой я сталкиваюсь при создании новых ресурсов, поэтому предположим, что база данных полностью пуста в начале каждого блока кода. Я уже преобразовал входящие данные, чтобы они соответствовали формату Rails.

# transformed incoming data
data = {
  id: 1234,
  title: '...',
  body: '...',
  accounted_times_attributes: [{
    id: 12345,
    units: '1.3'.to_d,
    type: 'work',
    billable: true,
  }, {
    id: 12346,
    units: '0.2'.to_d,
    type: 'travel',
    billable: false,
  }],
}

При создании не вложенного ресурса вы можете указать идентификатор (при условии, что он не занят), и он будет сохранен с предоставленным идентификатором.

article = Article.find_or_initialize_by(id: data[:id])
article.update(data.except(:accounted_times_attributes))
# The above will save and create a record with id 1234.

Однако приведенное выше не работает для вложенных ресурсов при использовании интерфейса приема вложенных атрибутов для метода обновления.

article = Article.find_or_initialize_by(id: data[:id])
article.update(data)

ActiveRecord :: RecordNotFound: Не удалось найти AccountsTime с идентификатором = 12345 для статьи с идентификатором = 1234

В результате я пытаюсь создать ресурсы с указанным идентификатором. Я подумал, что мог пропустить опцию переключения какого-либо режима find_or_initialize_by или find_or_create_by при предоставлении вложенных атрибутов. Я что-то здесь упускаю?

В настоящее время я использую следующую альтернативу (без простоты обработки ошибок):

article = Article.find_or_initialize_by(id: data[:id])
article.update(data.except(:accounted_times_attributes))

data[:accounted_times_attributes]&.each do |attrs|
  accounted_time = article.accounted_times.find_or_initialize_by(id: attrs[:id])
  accounted_time.update(attrs)
end

1 Ответ

0 голосов
/ 07 сентября 2018

Я думаю, что ваша проблема не в конфигурации accepts_nested_attributes_for, которая вроде бы в порядке.

Возможно, ваша проблема в том, что вы используете зарезервированное слово для модели Time,Попробуйте изменить название модели и протестируйте ее снова.

ОБНОВЛЕНИЕ:

Это кажется довольно странным, но при поиске той же проблемы я нашел этот ответ , который объясняет возможную причину ошибки вРельсы 3 и показывают два возможных решения.Не стесняйтесь проверить это, надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...