Rails:从控制器调用另一个控制器操作

时间:2022-12-01 22:44:15

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

我需要从控制器B调用控制器A中的create操作。

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

原因是当我从控制器B调用时,我需要重定向。

Can it be done in Rails?

它可以在Rails中完成吗?

9 个解决方案

#1


60  

You can use a redirect to that action :

您可以使用重定向到该操作:

redirect_to your_controller_action_url

More on : Rails Guide

更多关于:Rails指南

To just render the new action :

来呈现新的行动:

redirect_to your_controller_action_url and return

#2


36  

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

你现在的逻辑不是MVC,而是Rails,兼容。

  • 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.

也就是说你可以通过不同的控制器做同样的事情当你在控制器B的时候从控制器a召唤一个方法。

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

词汇是极其重要的,这就是我为什么坚持这么做的原因。

#3


33  

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

#4


29  

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

您可以使用url_for获取控制器和操作的URL,然后使用redirect_to访问该URL。

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

#5


13  

This is bad practice to call another controller action.

调用另一个控制器动作是不好的做法。

You should

你应该

  1. duplicate this action in your controller B, or
  2. 在控制器B中复制此操作
  3. wrap it as a model method, that will be shared to all controllers, or
  4. 将它包装为一个模型方法,它将被共享给所有的控制器,或者
  5. you can extend this action in controller A.
  6. 你可以在控制器A中扩展这个动作。

My opinion:

我的意见:

  1. First approach is not DRY but it is still better than calling for another action.
  2. 第一种方法并不枯燥,但它仍然比呼吁采取另一种行动要好。
  3. Second approach is good and flexible.
  4. 第二种方法是好的和灵活的。
  5. 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.

你可以发送到这个动作redirect_to param,它可以是你想要的任何路径。

#6


6  

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.

也许逻辑可以被提取到助手中?所有类都可以使用helper函数,不转移控件。您可以在其中检查它,或者是控制器名称,以查看它的调用方式。

#7


5  

Composition 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.

由于这个原因,应该设计控制器来分离代码的共享部分和自定义部分,而不是在控制器之间调用操作。这将有助于避免代码重复和打破MVC模式。

Although that can be done in a number of ways, using concerns (composition) 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.

希望有帮助。

#8


1  

You can call another action inside a action as follows:

你可以在下面的动作中调用另一个动作:

redirect_to action: 'action_name'

redirect_to行动:“action_name”

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

  def action2
  end
end

#9


-5  

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

将这些函数与控制器分离,并将它们放入模型文件中。然后在控制器中包含模型文件。

#1


60  

You can use a redirect to that action :

您可以使用重定向到该操作:

redirect_to your_controller_action_url

More on : Rails Guide

更多关于:Rails指南

To just render the new action :

来呈现新的行动:

redirect_to your_controller_action_url and return

#2


36  

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

你现在的逻辑不是MVC,而是Rails,兼容。

  • 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.

也就是说你可以通过不同的控制器做同样的事情当你在控制器B的时候从控制器a召唤一个方法。

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

词汇是极其重要的,这就是我为什么坚持这么做的原因。

#3


33  

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

#4


29  

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

您可以使用url_for获取控制器和操作的URL,然后使用redirect_to访问该URL。

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

#5


13  

This is bad practice to call another controller action.

调用另一个控制器动作是不好的做法。

You should

你应该

  1. duplicate this action in your controller B, or
  2. 在控制器B中复制此操作
  3. wrap it as a model method, that will be shared to all controllers, or
  4. 将它包装为一个模型方法,它将被共享给所有的控制器,或者
  5. you can extend this action in controller A.
  6. 你可以在控制器A中扩展这个动作。

My opinion:

我的意见:

  1. First approach is not DRY but it is still better than calling for another action.
  2. 第一种方法并不枯燥,但它仍然比呼吁采取另一种行动要好。
  3. Second approach is good and flexible.
  4. 第二种方法是好的和灵活的。
  5. 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.

你可以发送到这个动作redirect_to param,它可以是你想要的任何路径。

#6


6  

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.

也许逻辑可以被提取到助手中?所有类都可以使用helper函数,不转移控件。您可以在其中检查它,或者是控制器名称,以查看它的调用方式。

#7


5  

Composition 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.

由于这个原因,应该设计控制器来分离代码的共享部分和自定义部分,而不是在控制器之间调用操作。这将有助于避免代码重复和打破MVC模式。

Although that can be done in a number of ways, using concerns (composition) 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.

希望有帮助。

#8


1  

You can call another action inside a action as follows:

你可以在下面的动作中调用另一个动作:

redirect_to action: 'action_name'

redirect_to行动:“action_name”

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

  def action2
  end
end

#9


-5  

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

将这些函数与控制器分离,并将它们放入模型文件中。然后在控制器中包含模型文件。