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

时间:2011-04-23 21:58:59

标签: ruby-on-rails

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

原因是当我从控制器B打电话时,我需要以不同方式重定向。

可以在Rails中完成吗?

9 个答案:

答案 0 :(得分:62)

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

redirect_to your_controller_action_url

更多信息:Rails Guide

仅渲染新动作:

redirect_to your_controller_action_url and return

答案 1 :(得分:43)

要使用另一个控制器,请执行以下操作:

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

答案 2 :(得分:39)

你提出的逻辑不是MVC,而是Rails,兼容。

  • 控制器呈现视图或重定向

  • 方法执行代码

从这些考虑因素中,我建议您在控制器中创建方法并从您的操作中调用它们。

示例:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

那就是说你可以通过不同的控制器做同样的事情,并在控制器B中召唤来自控制器A的方法

词汇非常重要,这就是我坚持的原因。

答案 3 :(得分:30)

您可以使用url_for获取控制器和操作的网址,然后使用redirect_to转到该网址。

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

答案 4 :(得分:12)

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

你应该

  1. 在控制器B或
  2. 中复制此操作
  3. 将其包装为模型方法,将共享给所有控制器,或
  4. 您可以在控制器A中扩展此操作。
  5. 我的意见:

    1. 第一种方法不是DRY,但它仍然比要求采取其他行动更好。
    2. 第二种方法是好的和灵活的。
    3. 第三种方法是我过去常常做的事情。所以我只会举一些例子。

      def create
        @my_obj = MyModel.new(params[:my_model])
        if @my_obj.save
          redirect_to params[:redirect_to] || some_default_path
         end
      end
      
    4. 所以你可以发送到这个动作redirect_to param,它可以是你想要的任何路径。

答案 5 :(得分:6)

也许逻辑可以被提取到帮助器中?助手可用于所有类,不转移控制。您可以在其中检查,也许是控制器名称,以查看它是如何被调用的。

答案 6 :(得分:5)

Composition救援!

考虑到原因,不应该跨控制器调用操作,而应该设计控制器来分离代码的共享和自定义部分。这将有助于避免代码重复和破坏MVC模式。

虽然可以通过多种方式完成,但使用问题(composition)是一种很好的做法。

# 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

希望有所帮助。

答案 7 :(得分:1)

您可以按如下方式在操作中调用其他操作:

redirect_to action:'action_name'

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

  def action2
  end
end

答案 8 :(得分:-5)

将这些功能与控制器分开并将它们放入模型文件中。然后在控制器中包含模型文件。