Reputation: 1788
I'm using Devise and Pundit. To create a new profile page, the user has to be authorized to do so. This has been working fine since I first implemented it, but today it just started acting up with an error message:
Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
Here's my code from my Application controller:
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
...
private
def user_not_authorized(exception)
flash[:alert] = "Sorry, you are not authorized to perform this action."
redirect_to(request.referrer || root_path)
end
Here's my ProfilePage controller:
def new
@profile_page = ProfilePage.new
authorize @profile_page
end
def create
@profile_page = ProfilePage.new(profile_page_params)
respond_to do |format|
if @profile_page.save
format.html { redirect_to @profile_page, notice: 'Profile page was successfully created.' }
format.json { render :show, status: :created, location: @profile_page }
else
format.html { render :new }
format.json { render json: @profile_page.errors, status: :unprocessable_entity }
end
end
authorize @profile_page
end
Someone suggested that I add this line of code below flash[:alert]
:
self.response_body = nil
But now my user is redirected to the 'new profile' page again, rather than the successful profile page. It also tells the user that they are not authorized to complete this action, despite the fact that it HAS authorized them to do so.
Upvotes: 2
Views: 4278
Reputation: 1716
In the create action you have to put the authorization logic before saving the record:
You have to move
authorize @profile_page
at the top of your create action, after initializing the @profile_page
, like so:
def create
@profile_page = ProfilePage.new(profile_page_params)
authorize @profile_page
respond_to do |format|
if @profile_page.save
format.html { redirect_to @profile_page, notice: 'Profile page was successfully created.' }
format.json { render :show, status: :created, location: @profile_page }
else
format.html { render :new }
format.json { render json: @profile_page.errors, status: :unprocessable_entity }
end
end
end
Upvotes: 4