I have an update method in a controller. If params[:single] is a value of 1, I want to run a create_exception method that looks like this and not update the record:
before_action :create_exception, only: %i[ update ]
def update
if @event.update(event_params) ...
end
private
def create_exception
if params[:single] == 1
@exception = @event.event_exceptions.create(date: params[:exception_date])
respond_to do |format|
format.turbo_stream
format.html { redirect_to events_path, notice: "Event was successfully updated." }
format.json { head :no_content }
end
end
end
My first problem is that the create_exception method does not seem to be firing when I update an event. It just calls update and updates the info on the record which is not what I want. If params[:single] = 1 I want to create an expection and redirect back to the schedule without updating the event.
What is the best way to accomplish this?
CodePudding user response:
Parameter values are always strings, so check params[:single] == "1"
.
before_action is useful for doing things that should happen universally before actions are run, like checking permissions.
It should not be used to alter the behavior of a single action. That is action-at-a-distance.
Instead, check your params in the update method and return early.
def update
return create_event_exception if params[:single] == "1"
# update as normal
end
private
def create_event_exception
@exception = @event.event_exceptions.create(date: params[:exception_date])
respond_to do |format|
format.turbo_stream
format.html { redirect_to events_path, notice: "Event was successfully updated." }
format.json { head :no_content }
end
end
The full behavior of update is clear, and it does not rely on the reader knowing details of how before_action works.
CodePudding user response:
From the guide:
redirect_to and redirect_back do not halt and return immediately from method execution, but simply set HTTP responses. Statements occurring after them in a method will be executed. You can halt by an explicit return or some other halting mechanism, if needed.
It also says:
If a "before" filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter, they are also cancelled.
So I think the problem, given the code you've shown us, it will only halt the execution if it hits the format.html { redirect_to events_path, notice: "Event was successfully updated." }
Are you hitting this controller with an HTML request? The format: turbo_stream
and format: json
aren't doing any redirect so they will not halt the execution of the action. If you are making a regular HTML request then can you add some of the web console code to your question for further troubleshooting?