Home > Software design >  Is there a way to validate and save an array of objects in ruby on rails' ActiveRecord?
Is there a way to validate and save an array of objects in ruby on rails' ActiveRecord?

Time:08-28

I want to save an event to the DB, the event contains a tickets array, which intern contains objects with ticket information as shown below

event params

These are my functions for validating the params

def event_params
  params.require(:event).permit(:title, :description, :event_type, :category_id, :county_id, :web_url, :venue_url, :venue_name, :poster, :video_url, :start_date, :end_date, :published_date, :is_private, :status, :age_limit)
end



def ticket_params
  params.require(:event).permit(tickets: [:name, :price, :quantity, :detail, :status])
end

and this is how I am creating the event and tickets

def create
    @event = Event.new(event_params.merge(user_id: current_user.id))
    
    if @event.save
      ticket_params[:tickets].each do |ticket|
        @event.tickets.create(ticket)
      end

      render json: @event.to_json(include: :tickets), status: :created
    else
      render json: @event.errors, status: :unprocessable_entity
    end
end

I am currently getting this error: postman error

CodePudding user response:

It seems as if no nested array is present under event_params[:tickets]. Use debugger in your controller to see why.

CodePudding user response:

after using debugger as recommended by @installero in the above answer, I noticed, when I chain the validation, tickets_params[:tickets] is nil, but when i separated them, it worked

def ticket_params
  params.require :tickets
  params.permit :tickets => [:name, :price, :quantity, :detail, :status]
end

but the best approach recommended by @masroor in the comment is to include accepts_nested_attributes_for :tickets in the Event model according to this doc

and then renaming the tickets params to tickets_attributes

the json params

 {
    "title": "Goatfest Live Music Festival 2022",
    "event_type": "Festival",
     ...
    "tickets_attributes": [
      {
          "name": "WIP",
          "price": 100,
          ...
      },
      {
          "name": "Sit",
          "price": 50,
          ...
      }
   ]
}

the validation function

def event_params
  params.require(:event).permit(:title, :event_type, tickets_attributes: [:name, :price])
end

and finally, the create action

def create
  @event = Event.new(event_params.merge(user_id: current_user.id))

  if @event.save
    render json: @event.to_json(include: :tickets), status: :created
  else
    render json: @event.errors, status: :unprocessable_entity
  end
end
  • Related