Saturday, 6 June 2015

Different ways to early returns from controllers

In some scenarios we don't need to execute full code of a controller method and want to return in-between.
So Here are different ways to early return from the controller methods :

1) redirect_to path and return


class Controller1 < ApplicationController
  def method1
    if something
      redirect_to edit_x_path(@object) and return
    end

    if something_else
      redirect_to index_path(@object) and return
    end
    # Code
    # Code
    #....etc
  end
end

It is the classic way. It is working properly If all redirects and return are in same method. If we call method2 in our method1 and try to redirect and return from method2, then it will give double render or redirect error.

So here are another ways to handle above scenario.

2) Extracted method return with AND


class Controller1 < ApplicationController
  def method1
    method2 and return
    # even more code over there ...
  end

  private

  def method2
    unless @var.some_condition? 
      redirect_to edit_x_path(@var) and return true
    end

    if some_condition_x?
      redirect_to y_path(@var) and return true
    end
  end
end

In this technique we need to write return true instead of only return. If you forgot to write true  
It can cause issue.

3) Extracted method return with OR


class Controller1 < ApplicationController
  def method1
    method2 or return
    # even more code over there ...
  end

  private

  def method2
    unless @var.some_condition? 
      redirect_to edit_x_path(@var) and return 
    end

    if some_condition_x?
      redirect_to y_path(@var) and return 
    end
  end
  return true
end

In this case we must need to add return true at the end.

4) Extracted method return via yield


class Controller1 < ApplicationController
  def method1
    method2  {return}
    # even more code over there ...
  end

  private

  def method2
    unless @var.some_condition? 
      redirect_to edit_x_path(@var) and yield 
    end

    if some_condition_x?
      redirect_to y_path(@var) and yield 
    end
  end
end

We can say it explicit return. It depends on callback block. If callback block contains {return} then it will perform early return.

5) Return with performed? method


class Controller1 < ApplicationController
  def method1
    method2; return  if performed?
    # even more code over there ...
  end

  private

  def method2
    unless @var.some_condition? 
      redirect_to edit_x_path(@var) and return 
    end

    if some_condition_x?
      redirect_to y_path(@var) and return 
    end
  end
end

performed? method is define in ActionController::Metal controller. Using this method we can test whether  render or redirect already performed. 

1 comment:

  1. Thanks for this selfless act. really feel very happy about sharing your useful update with us.

    Java training in chennai

    ReplyDelete