从另一个控制器渲染控制器操作

38
我认为代码更加明确

选项 A

class RedirectController < ApplicationController
  def index
    redirect_to :controller => 'posts', :action => 'show', :id => 1
    # it works
  end
end

选项B
class RedirectController < ApplicationController
  def index
    render :controller => 'posts', :action => 'show', :id => 1
    # it doesn't work
  end
end

在(B)中是否可以加载另一个控制器中的其他操作?(而不仅仅是视图)如何实现? 谢谢

为什么你想要这样做?如果你告诉我们你试图解决的根本问题,可能会更好。 - John Topley
“根本问题”是我想自由设置一些URL而不必触碰routes.rb文件。 - user142913
3
仅为澄清,您的选项A不会呈现来自另一个控制器的操作,它会使用重定向回答当前请求,将浏览器指向另一个控制器(因此导致第二个请求触及另一个控制器)。然而,render :template => 'posts/show'直接呈现了另一个控制器的模板。当然,您需要设置一些东西让模板显示(例如您的@post变量)。我不确定您尝试做什么,但通常情况下,您不能在不触及routes.rb的情况下设置URL,因为这是routes.rb的作用所在。 - Zargony
如果您不想分配@post变量,应该使用“redirect_to”,因为如果您使用“render”,则在您的操作中的代码不会被执行,“render”只是呈现其他视图文件以填充当前数据。 - Bohdan
2个回答

65

尝试使用render 'posts/show'render :template => 'posts/show'


谢谢,它可以双向工作,但不是很干净,因为我不得不添加@post ..@post = Post.find 1 render 'posts/show' - user142913
这个可以工作,但不能在执行模板周围呈现另一个控制器的模板。有办法强制执行吗? - elsurudo
3
您可以使用:layout =>选项强制指定布局。 - Bohdan
2
这将呈现与路由“posts/show”相关联的内容,它不会呈现#posts控制器中的#show操作。这是两个完全不同的概念,经常重叠。 - James Moore
1
想象一下在routes.rb中的以下行:get 'posts/show',controller::something_else,action::erase_the_database。或者想象一个没有posts/show路由的routes.rb。问题非常具体:它想呈现一个控制器/操作对,而不是一个路由。 (话虽如此,我认为你的答案很有用,即使它并不真正回答所提出的问题。) - James Moore

7
只需渲染模板。
def index
  render 'posts/show'
end

这个也可以工作。
def index
  render template: 'posts/show'
end

如果您想在其他布局中呈现

def index
  render template: 'posts/show', layout: 'different_layout' 
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接