Home > Net >  Rails - How to break out of a controller method?
Rails - How to break out of a controller method?

Time:01-12

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?

  • Related