保存父级时embeds_many子级属性未保留

时间:2019-01-22 09:19:47

标签: ruby-on-rails angular mongodb api mongoid

我一直在找几天没有找到我所要解决的问题的确切答案,就像这样简单:我有一个简单的模型,有书籍和作者。一本书嵌入了许多作者,而作者被嵌入其中。但是,每当我保存一本新书时,作者数组都不会保留。

我所拥有的是一个有角度的7应用程序,称为ROR API。我的Rails版本是5.2.2。我正在使用mongoid 7.0进行持久化。

我的API是使用rails g支架以及--api和--skip-active-record标志生成的。

我首先遇到了属性映射问题。当Rails等待表单lower_snake_case vars时,我的Angular APP在lowerCamelCase中发送JSON。我设法通过在初始化程序中添加一个中间件(如果我对此不正确,请纠正我)来绕过此问题,该中间件将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如何对其进行处理:

Request sent by angular app

Request received and processed by Rails

我们可以在书本对象中看到

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

作者已消失,尽管他们已出现在服务器收到的请求中。

然后我的问题是:对此有什么解决方案,或者至少我缺少什么?使用嵌入式文档和 accepts_nested_attributes_for 时,Mongoid不会自动保存子级吗?每次在控制器中保存父母时,是否应该手动保存孩子?

预先感谢您的帮助

1 个答案:

答案 0 :(得分:0)

您必须使用嵌套属性来保存子记录

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: Nested attributes

以这种格式通过眼动仪

{"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