使用另一个控制器的视图渲染一个控制器

44

我有一个QuestionController 现在我有AnotherQuestionController,其中的操作应该使用位于app/views/question/中的模板和部分呈现。 这是可能的吗?看起来应该是可以的。

我已经尝试过

render :template => "question/answer"

但是 answer.html.erb 包括一些 partials,我得到了如下错误:

"在视图路径中找不到 another_question/_my_partial.erb "

那么,有没有办法告诉 Rails "将 AnotherQuestionController 视为 QuestionController,然后在 app/views/question 中查找视图和 partials"?还是我必须创建一个 app/views/another_question 目录 —— 这会导致重复(这不可能是 Rails 的做法)。

谢谢

4个回答

64

模板渲染应该正常工作

 render :template => "question/answer"

你遇到的问题是由于局部模板文件查找位置错误导致的。解决方法很简单,只需要在任何共享模板中将你的局部模板文件设为绝对路径即可。例如,question/answer.html.erb 应该包含以下内容:

<%= render :partial => 'question/some_partial' %>

不是通常的

<%= render :partial => 'some_partial' %> 

在Rails 3.x中有任何新的方法吗?我问这个问题是因为我正在使用一个宝石(gem),它提供了帮助程序来自动完成视图中的渲染(否则你的解决方案将起作用)。我宁愿不要覆盖那个宝石(gem)的帮助程序。谢谢! - montrealmike

17

你可以使用以下方法实现:

render 'question/answer'

这是否也会触发该控制器中的所有 before_actions? - MikanPotatos
@MikanPotatos 它根本不会触发那个控制器。 - BenKoshy
就我个人而言,我认为 render 'questions/answer' 也可以(复数形式)。例如 render 'studios/show' - stevec

2
Rails使用一系列前缀来解析模板和局部视图。虽然你可以明确指定一个前缀(如“question/answer”),但是这种方法会失败,如果模板本身包含对其他局部视图的未限定引用。
假设您有一个ApplicationController超类,QuestionController从中继承,则Rails查找模板的位置按顺序为“app/views/question/”和“app/views/application/”。 (实际上它还会查找一系列视图路径,但为简单起见,我忽略了这一点。)
给出以下内容:
class QuestionController < ApplicationController
end

class AnotherQuestionController < ApplicationController
end

QuestionController._prefixes
# => ["question", "application"]
AnotherQuestionController._prefixes
# => ["another_question", "application"]

解决方案#1:将该部分文件放置在“app/views/application/”而非“app/views/question/”下,这样它将对两个控制器都可用。

解决方案#2:如果适合的话,可以继承QuestionController。

class AnotherQuestionController < QuestionController
end
=> nil
AnotherQuestionController._prefixes
# => ["another_question", "question", "application"]
解决方案 #3. 定义 AnotherQuestionController 类方法 local_prefixes。这个方法是在 Rails 4.2 中添加的。
class AnotherQuestionController < ApplicationController
  def self.local_prefixes
    super + ['question']
  end
end
AnotherQuestionController._prefixes
# => ["another_question", "question", "application"]

很重要的是说:第二种解决方案在我的情况下有效,当我在“AnotherQuestionController”上执行操作并呈现包含部分渲染的视图时。谢谢! - Rafael Gomes Francisco

-1

谢谢,我会研究一下。不过看起来工作量挺大的。我本以为render()可以使用选项来指定另一个控制器的视图/局部视图。唉,算了。 - Paul

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