Свойство дочернего элемента Embeds_many не сохраняется при сохранении родительского свойства - PullRequest
0 голосов
/ 22 января 2019

Я искал несколько дней, не находя точного ответа на мою проблему, которая так проста: у меня есть простая модель, с книгами и авторами. Книга встраивает много авторов, а автор встраивается в книгу. Но всякий раз, когда я сохраняю новую книгу, массив авторов не сохраняется.

То, что у меня есть, это угловое 7 приложение, вызывающее ROR API. Мои Rails версии 5.2.2. Я использую mongoid 7.0 для настойчивости.

Мой API был создан с помощью rails g scaffold и с флагами --api и --skip-active-record.

Сначала у меня была проблема с сопоставлением моих свойств. Мое Angular APP отправляет JSON в lowerCamelCase, когда Rails ожидает формирования файла lower_snake_case. Мне удалось обойти эту проблему, добавив промежуточное программное обеспечение (исправьте меня, если я ошибаюсь в этом) в моих инициализаторах, которое преобразует camelCase в snake_case.

# Transform JSON request param keys from JSON-conventional camelCase to
# Rails-conventional snake_case:
ActionDispatch::Request.parameter_parsers[:json] = -> (raw_post) {
   # Modified from action_dispatch/http/parameters.rb
   data = ActiveSupport::JSON.decode(raw_post)
   data = {:_json => data} unless data.is_a?(Hash)

   # Transform camelCase param keys to snake_case:
   data.deep_transform_keys!(&:underscore)
}

Из того, что я нашел в поисках моей проблемы, это могло быть проблемой с сильными параметрами, поэтому я попытался разобраться с этим в моих book_params

def book_params
  #params.fetch(:book, {})
  params.require(:book).permit(:title, :release_date, authors_attributes: [:name, :last_name, :birth_date])
end

Это моя модель:

class Person
  include Mongoid::Document
  field :last_name, type: String
  field :first_name, type: String
  field :birth_date, type: Date
end

class Author < Person
  include Mongoid::Document
  embedded_in :book
end

class Book
 include Mongoid::Document
 field :title, type: String
 field :release_date, type: Date
 embeds_many :authors 
 accepts_nested_attributes_for :authors
end

И это POST в контроллере моей книги (создан с помощью Rails)

  # POST /books
  def create

    @book = Book.new(book_params)

    if @book.save
      render json: @book, status: :created, location: @book
    else
      render json: @book.errors, status: :unprocessable_entity
    end
  end

А вот пример тела, отправленного, полученного и как оно обрабатывается Rails:

Запрос отправлен через угловое приложение

Запрос, полученный и обработанный Rails

Мы можем видеть в книге объект

"book"=>{"title"=>"azerty", "release_date"=>"2019-01-21T16:10:19.515Z"}}

что авторы исчезли, хотя они присутствовали в запросе, полученном сервером.

Тогда у меня вопрос: каково это решение или, по крайней мере, что я пропускаю? Разве Mongoid не сохраняет автоматически дочерние элементы при использовании встроенных документов и acceptpts_nested_attributes_for ? Должен ли я вручную сохранять детей каждый раз, когда родительский элемент сохраняется в моем контроллере?

Заранее спасибо за помощь

1 Ответ

0 голосов
/ 22 января 2019

Вы должны использовать вложенные атрибуты для сохранения дочерних записей.

Добавить следующую строку в book модель

accepts_nested_attributes_for :authors

И передать параметры авторов в author_attributes, например:

{title: 'test', release_date: '', author_attributes: [{first_name: '', other_attributes of author}, {first_name: '', , other_attributes of author}]}

для более подробной информации, пожалуйста, проверьте Mongoid: вложенные атрибуты

Передайте параметры в этом формате

{"title"=>"test", "release_date"=>"2019-01-22", "book"=>{"title"=>"test", "release_date"=>"2019-01-22", "authors_attributes"=>[{"first_name"=>"test name", "last_name"=>"test", "birth_date"=>"2019-01-22T09:43:39.698Z"}]}}

Разрешить параметры книги

def book_params
   params.require(:book).premit(:first_name, :last_name, authors_attributes: %i[first_name last_name birth_date])
end
...