I have two rails app : one is a "front-end app" responsible for displaying data, taking input from the user and sending data to the API (the second app). The second is an API dealing with database operations and sending JSON to the front end app.
I have an action where my user decides how many rooms
he wants to create in his hotel
and how many beds
should he create in each room
. The form on the front end app looks like that :
<h1>Add Rooms</h1>
<form action="http://localhost:3000/hotels/<%=params[:hotel_id]%>/rooms/multiple_create" method="post">
<input name="authenticity_token" value="<%= form_authenticity_token %>" type="hidden">
<div class="form-group">
<%= label_tag 'room[room_number]', "Number of rooms" %>
<input type="number" name="room[room_number]" required>
</div>
<div class="form-group">
<%= label_tag "room[bed_number]", "Number of beds by room" %>
<input type="number" name= "room[bed_number]" required>
</div>
<div class="form-group">
<%= label_tag "room[content]", "Room Type" %>
<input type="text" name= "room[content]" required>
</div>
<input type="submit">
<% if @errors %>
<ul class="list-unstyled">
<%@errors.each do |error|%>
<li class="has-error"><%=error%></li>
<% end -%>
</ul>
<% end -%>
</form>
This form is linked to my RoomsController#multiple_create action on the front-end app that is responsible for sending the form data to the API :
class RoomsController < ApplicationController
def multiple_new
end
def multiple_create
@response = HTTParty.post(ENV['API_ADDRESS']+'api/v1/hotels/'+ params[:hotel_id]+'/rooms/multiple_create',
:body => { :room =>{
:room_number => params[:room][:room_number],
:bed_number => params[:room][:bed_number],
}
}.to_json,
:headers => { 'X-User-Email' => session[:user_email], 'X-User-Token'=> session[:user_token], 'Content-Type' => 'application/json' } )
# Erreur Mauvais Auth Token
if @response["error"] == "You need to sign in or sign up before continuing."
redirect_to unauthorized_path
# erreur de validation
elsif @response["error"]
raise
@errors = @response["errors"]
render :multiple_new
else
raise
redirect_to account_path(account_id)
end
end
end
I have a corresponding method in my room_controller.rb that is responsible for creating rooms, beds for each rooms and slots for each beds. On the API I am using Pundit for authorization.
def multiple_create
i = 0
start_date = Date.today
ActiveRecord::Base.transaction do
while i < params[:room_number].to_i
@room = @hotel.rooms.build(room_params)
authorize @room
if @room.save
(0...params[:bed_number].to_i).each do
@bed = @room.beds.create!
for a in 0...60
@bed.slots.create!(available: true, date: start_date + a.days )
end
end
i+=1
else
break
end
end
end
if i == params[:room_number]
render json: {success: "All rooms and beds where successfully created"}
else
render json: {error: "There was a problem during room creation process. Please try again later"}
end
end
Everytime I try to post on this method I get :
Pundit::AuthorizationNotPerformedError - Pundit::AuthorizationNotPerformedError:
pundit (1.0.1) lib/pundit.rb:103:in `verify_authorized
It seems to me I am actually calling authorize @room before saving the new room during the loop. I have a method multiple_create in my room_policy.rb
:
def multiple_create?
(user && record.hotel.account.admin == user) || (user && user.manager && (user.account == record.hotel.account))
end
And in my API base_controller I have :
after_action :verify_authorized, except: :index
Why am I getting this pundit error here ?