Я видел эти обсуждения длинных тем / проблем # 979 и # 795 на JSON: репо API несколько дней назад, очевидно, что JSON API не имеет истинного решения для accepts_nested_attributes_for
.
Я не знаю, является ли это лучшим решением, но обходной путь к этому - избавиться от маршрута к вашим belongs_to
и has_many/has_one
ассоциациям.
Примерно так:
Ваш rout.rb :
Rails.application.routes.draw do
resources :contacts do
resource :kind, only: [:show]
resource :kind, only: [:show], path: 'relationships/kind'
resource :phones, only: [:show]
resource :phones, only: [:show], path: 'relationships/phones'
resource :phone, only: [:update, :create, :destroy]
# These relationships routes is merely a suggestion of a best practice
resource :phone, only: [:update, :create, :destroy], path: 'relationships/phone'
resource :address, only: [:show, :update, :create, :destroy]
resource :address, only: [:show, :update, :create, :destroy], path: 'relationships/address'
end
root 'contacts#index'
end
Их реализуют ваши контроллеры .
phones_controller.rb в соответствии с приведенным выше примером:
class PhonesController < ApplicationController
before_action :set_contacts
def update
phone = Phone.find(phone_params[:id])
if phone.update(phone_params)
render json: @contact.phones, status: :created, location: contact_phones_url(@contact.id)
else
render json: @contact.errors, status: :unprocessable_entity
end
end
# DELETE /contacts/1/phone
def destroy
phone = Phone.find(phone_params[:id])
phone.destroy
end
# POST contacts/1/phone
def create
@contact.phones << Phone.new(phone_params)
if @contact.save
render json: @contact.phones, status: :created, location: contact_phones_url(@contact.id)
else
render json: @contact.errors, status: :unprocessable_entity
end
end
# GET /contacts/1/phones
def show
render json: @contact.phones
end
private
# Use callbacks to share common setup or constraints between actions.
def set_contacts
@contact = Contact.find(params[:contact_id])
end
def phone_params
ActiveModelSerializers::Deserialization.jsonapi_parse(params)
end
end
Сделав это, вы сможете запросить телефон POST обычно через отдельный контакт, например:
POST на http://localhost:3000/contacts/1/phone с корпусом:
{
"data": {
"type": "phones",
"attributes": {
"number": "(+55) 91111.2222"
}
}
}
Ответ или GET на http://localhost:3000/contacts/1/phones:
{
"data": [
{
"id": "40",
"type": "phones",
"attributes": {
"number": "(55) 91111.2222"
},
"relationships": {
"contact": {
"data": {
"id": "1",
"type": "contacts"
},
"links": {
"related": "http://localhost:3000/contacts/1"
}
}
}
}
]
}
Надеюсь, что ответ