Rails: call another controller action from a controller

Ruby on-Rails

Ruby on-Rails Problem Overview


I need to call the create action in controller A, from controller B.

The reason is that I need to redirect differently when I'm calling from controller B.

Can it be done in Rails?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

To use one controller from another, do this:

def action_that_calls_one_from_another_controller
  controller_you_want = ControllerYouWant.new
  controller_you_want.request = request
  controller_you_want.response = response
  controller_you_want.action_you_want
end

Solution 2 - Ruby on-Rails

You can use a redirect to that action :

redirect_to your_controller_action_url

More on : Rails Guide

To just render the new action :

redirect_to your_controller_action_url and return

Solution 3 - Ruby on-Rails

The logic you present is not MVC, then not Rails, compatible.

  • A controller renders a view or redirect

  • A method executes code

From these considerations, I advise you to create methods in your controller and call them from your action.

Example:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

That said you can do exactly the same through different controllers and summon a method from controller A while you are in controller B.

Vocabulary is extremely important that's why I insist much.

Solution 4 - Ruby on-Rails

You can use url_for to get the URL for a controller and action and then use redirect_to to go to that URL.

redirect_to url_for(:controller => :controller_name, :action => :action_name)

Solution 5 - Ruby on-Rails

This is bad practice to call another controller action.

You should

  1. duplicate this action in your controller B, or
  2. wrap it as a model method, that will be shared to all controllers, or
  3. you can extend this action in controller A.

My opinion:

  1. First approach is not DRY but it is still better than calling for another action.

  2. Second approach is good and flexible.

  3. Third approach is what I used to do often. So I'll show little example.

     def create
       @my_obj = MyModel.new(params[:my_model])
       if @my_obj.save
         redirect_to params[:redirect_to] || some_default_path
        end
     end
    

So you can send to this action redirect_to param, which can be any path you want.

Solution 6 - Ruby on-Rails

Perhaps the logic could be extracted into a helper? helpers are available to all classes and don't transfer control. You could check within it, perhaps for controller name, to see how it was called.

Solution 7 - Ruby on-Rails

[Composition][1] to the rescue!

Given the reason, rather than invoking actions across controllers one should design controllers to seperate shared and custom parts of the code. This will help to avoid both - code duplication and breaking MVC pattern.

Although that can be done in a number of ways, using concerns ([composition][1]) is a good practice.

# controllers/a_controller.rb
class AController < ApplicationController
  include Createable

  private def redirect_url
    'one/url'
  end
end

# controllers/b_controller.rb
class BController < ApplicationController
  include Createable

  private def redirect_url
    'another/url'
  end
end

# controllers/concerns/createable.rb
module Createable
  def create
    do_usefull_things
    redirect_to redirect_url
  end
end

Hope that helps. [1]: https://en.wikipedia.org/wiki/Object_composition

Solution 8 - Ruby on-Rails

You can call another action inside a action as follows:

redirect_to action: 'action_name'

class MyController < ApplicationController
  def action1
   redirect_to action: 'action2'
  end

  def action2
  end
end

Solution 9 - Ruby on-Rails

Separate these functions from controllers and put them into model file. Then include the model file in your controller.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionddayanView Question on Stackoverflow
Solution 1 - Ruby on-RailsSammy LarbiView Answer on Stackoverflow
Solution 2 - Ruby on-RailsSpyrosView Answer on Stackoverflow
Solution 3 - Ruby on-RailsapneadivingView Answer on Stackoverflow
Solution 4 - Ruby on-RailsaustinView Answer on Stackoverflow
Solution 5 - Ruby on-Railsfl00rView Answer on Stackoverflow
Solution 6 - Ruby on-RailsMichael DurrantView Answer on Stackoverflow
Solution 7 - Ruby on-RailsOleg AfanasyevView Answer on Stackoverflow
Solution 8 - Ruby on-RailsCodecPMView Answer on Stackoverflow
Solution 9 - Ruby on-RailsMichale.GaoclView Answer on Stackoverflow