Double render

504 views

What's the behavior of this method ?

def show
  @event = Event.find(params[:id])
  @event.remote? # => true

  if @event.remote?
    render action: "roblox_show"
  end

  render action: "show"
end

The correct answer is

It renders "roblox_show"

It renders "show"

It render both views

It raises DoubleRenderError

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

Explanation

Rails developers often encounter the

"Can only render or redirect once per action"

error, typically due to a misunderstanding of how render works.

The error arises when there are multiple render calls within the same action.

For instance, consider the following problematic code:

def show
  @event = Event.find(params[:id])

  if @event.remote?
    render action: "roblox_show"
  end

  render action: "show"
end

Here if @event.remote? returns true both render action: "roblox_show" and render action: "show" are called simultaneously.

To resolve this issue, ensure a single call to render or redirect in a code path.

Using return helps in this case:

def show
  @event = Event.find(params[:id])

  if @event.remote?
    render action: "roblox_show"
    return
  end

  render action: "show"
end

An alternative approach, leveraging implicit render, can be used without errors:

def show
  @event = Event.find(params[:id])

  if @event.remote?
    render action: "roblox_show"
  end
end

This version successfully renders the appropriate template based on the condition, addressing the error and maintaining code clarity.

Indeed, if @event.remote? returns false, the show method returns and ActionController returns the corresponding view for you.

Voilà!

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

RubyCademy ©