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


118

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

原因是从控制器B调用时,我需要进行不同的重定向。

可以在Rails中完成吗?



您是在谈论POST还是GET动作?如果为GET,则只需重定向到该操作即可。但是原因尚不清楚,因为您可以从控制器A重定向到所需的任何URL。
Voldy

Answers:


64

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

redirect_to your_controller_action_url

更多信息:Rails指南

只渲染新动作:

redirect_to your_controller_action_url and return

5
抱歉,您能说出第一行和第二行有什么区别吗?我认为首先将执行剩余的代码行,然后重定向。那是对的吗?
aks

我在想,也许最后一个例子是错字,应该render代替redirect_to。你怎么说@Spyros?
Magne

1
@spyros,您好,redirect_to不允许使用post: :method,这对于create第一次重定向到@ddayan要求的另一个控制器的现有动作特别有用。我有类似的情况,在某些情况下,我应该创建另一个对象。可以调用create
DRYer

53

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

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

18
如果您希望仍然执行回调,则可以controller_you_want这样做controller_you_want.process(:action_you_want)
Constantijn Schepens

3
谢谢!这对于不需要重定向的情况非常有用,您只需要一个快速的解决方案就可以将操作从一个控制器转移到另一个控制器。重定向确实有些不同。另外:render status: :ok, json: JSON.parse(controller.render(:action_you_want).first)似乎可以从其他控制器返回JSON
Yourpalal '17

1
很好的答案,正是我想要的。一个问题-请求参数需要采用什么格式?我认为他们生活在下面,controller_you_want.request但无法通过散列或参数实例获得触发。
SRack,2017年

我不确定您在问@SRack。将params变得可用controller_you_want通过设置request在第3行。那是你要的吗
萨米·拉尔比

1
尝试在rails 5中进行渲染,应该是render html: controller_you_want.process(:action_you_want)
nazar kuliyev

41

您提供的逻辑不是MVC,然后不是Rails,兼容。

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

  • 一种执行代码的方法

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

例:

 def index
   get_variable
 end

 private

 def get_variable
   @var = Var.all
 end

也就是说,您可以通过不同的控制器执行完全相同的操作,并在控制器B中从控制器A 召唤方法

词汇非常重要,这就是为什么我坚持很多。


我知道我不应该这样做,但这不是我的应用程序的一部分,仅用于测试和评估我的应用程序。
ddayan 2011年

9
喜欢它..从渲染中分离出方法,然后在需要时调用单个方法。只是一个问题.. get_variable现在如何从另一个控制器调用?
FloatingRock

1
@FloatingRock刚刚注意到您的问题/评论:您有几个选择:可以在共同祖先中定义,也可以包括共同mixin
窒息

热爱答案,不确定末尾的句子片段
Gerard Simpson

30

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

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

1
另一个似乎不适合我,看起来更好,但是如何传递参数?
msanjay 2014年

3
@msanjay,您可以将它们作为其他参数传递给url_for。例如redirect_to url_for(:controller => :controller_name, :action => :action_name, :param1 => :val1, :param2 => :val2)将导致/contorller_name/action_name?param1=val1&param2=val2。查看文件
Ariel Allon 2014年

如果我尝试从“ Module :: MyController”之类的控制器中将redirect_to到“ MyOtherController”之类的根控制器,它将解析为调用“ module / MyOtherController” ..知道如何调用根吗?
ggez44 '18

12

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

你应该

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

我的看法:

  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

因此,您可以发送到该操作redirect_to参数,该参数可以是您想要的任何路径。


嗨,对于解决方案B作为模型方法包装,如果根本没有模型,该如何包装?我们正在研究搜索引擎,并希望从其他引擎调用搜索引擎中的搜索视图。根本没有用于搜索操作的数据模型。
user938363 2013年

@ user938363-也许两个动作都呈现相同的视图(即使这些动作在不同的控制器中)。“ render”调用本身将被复制,但是它本身只是重复的一行,还不错。如果您有很多逻辑可以准备参数散列以传递给render调用,则可以通过将其移入其自己的文件(可能是中的模型,/models或者中的普通类或模块/lib)来避免重复该操作。唯一的问题是,如果您的控制器通过实例变量与视图进行通信-您必须以其他方式解决该重复问题。
antinome

如果您有一个UserController可以创建一个新的User(注册),并且成功后想要调用SessionsController并对用户进行身份验证,该怎么办?在这种情况下,您将以一种或另一种方式调用SessionsController。有什么想法吗?
dipole_moment 2015年

为什么这是一个不好的做法?Sammy Lambi答案有什么问题?
vasilakisfil

7

也许可以将逻辑提取到帮助程序中?所有班级都可以使用助手,并且不转移控制权。您可以在其中检查(也许是控制器名称)以查看其调用方式。


6

作文以营救!

给出了原因,而不是跨控制器调用动作,应该设计控制器来分离代码的共享和自定义部分。这将有助于避免代码重复和破坏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

希望有帮助。


2

您可以在一个动作中调用另一个动作,如下所示:

redirect_to action:'action_name'

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

  def action2
  end
end

-6

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


不好的建议。将混乱的职责,指向拥有MVC。在模型等会话/ cookie的调用问题
艾因Tohvri
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.