mercredi 2 novembre 2016

Saving sub object (via has_many) in create method rails

I've been trying to save sub-objects in a controller on my rails API.

My API is to create and organize congresses data.

One congres has one or many hotels, and hotels can have one or many hotel_various_infos.

The JSON I'm sending through POST /congresses is as following :

{
  "name": "Congress' name",
  "subtitle": "",
  "place": "cologne, germany",
  "date_from": "2016-10-22T00:00:00.000Z",
  "date_to": "2016-10-25T00:00:00.000Z",
  "host_company": "Hosting company",
  "host_logo_url": "http://ift.tt/2f0bUXn",
  "color" : "#121212",
  "template_id" : "1",
  "hotels": [
    {
      "name": "radisson blue Cologne",
      "address": "Messe Kreisel 3",
      "postal_code": "DE-50679",
      "city": "Cologne",
      "country": "Germany",
      "phone_nbr": "+49221277200",
      "check_in_time": "15:00",
      "check_out_time": "12:00",
      "hotel_various_infos": [
        {
            "title": "Welcome Desk",
            "content": "Should you require any assistance during your stay, a *** welcome desk will be open each day in the hotel lobby."
        }
      ]
    }
  ]
}

Here you can find my models :

congres.rb

class Congress < ApplicationRecord
  has_many :hotels, autosave: true
  has_many :agenda_events, autosave: true
end

hotel.rb

class Hotel < ApplicationRecord
  belongs_to :congress
  has_many :hotel_various_infos, autosave: true
end

hotel_various_info.rb

class HotelVariousInfo < ApplicationRecord belongs_to :hotels end

And this is my congresses' controller :

  # POST /congresses
  def create
    @congress = Congress.new(congress_params)
    hotels_params.each do |hotel_param|
      @congress.hotels.new(hotel_param)
      p '>>'
      p hotel_info_params
      p '<<'
      hotel_info_params.each do |hotel_info_param|
        @congress.hotels.hotel_various_infos.new(hotel_info_param)
      end
    end


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


  # Only allow a trusted parameter "white list" through.
  def congress_params
    params.require(:congress).permit(
        :name,
        :subtitle,
        :place,
        :date_from,
        :date_to,
        :host_company,
        :host_logo_url,
        :color,
        :template_id,
        :hotels,
        :hotel_various_infos
    )
  end

  def hotels_params
    params.permit(
        hotels: [:name,
                 :address,
                 :postal_code,
                 :city, :country,
                 :phone_nbr,
                 :check_in_time,
                 :check_out_time
        ]
    ).require(:hotels)
  end

  def hotel_info_params
    params.permit(hotel_various_infos: [:title, :content]).require(:hotel_various_infos)
  end

I'm not sure about my usage of strong parameters.

I get a "exception": "#", when calling this route.

Congres and its hotel are perfectly handled when "hotel_various_info" handling is removed.

When I call /congresses/{ID} I get the congres, hotels, and hotel_various_informations without any problem.

Thanks for your help.

Aucun commentaire:

Enregistrer un commentaire