【问题标题】:Rails 3 render action from another controllerRails 3 从另一个控制器渲染动作
【发布时间】:2011-08-28 10:47:45
【问题描述】:

我需要渲染另一个控制器动作<%= render "controller/index" %> 我得到这个错误

缺少带有 {:formats=>[:html], :locale=>[:en, :en], :handlers=>[:rjs, :rhtml, :rxml, :erb, :builder 的部分控制器/索引]} 在视图路径“/path_to/app/views”中

如何将另一个控制器操作呈现到视图中但不向客户端发送重定向? 我试过了

<%=render :action => "index", :controller=>"controller" %>

但它似乎不起作用。

【问题讨论】:

  • 您在views/your_controller/ 中有index.html.erb 吗?
  • 为什么不使用重定向到正确的控制器操作?
  • 因为动作的逻辑可能完全不同,而这些动作之间唯一的共同点就是视图。

标签: ruby-on-rails-3 erb


【解决方案1】:

尝试渲染模板:

<%= render :template => "controller/index" %> 

或文件:

<%= render :template => "#{Rails.root}/app/controllers/controller/index" %> 

而且我相信你应该通过控制器来渲染它,只要它更方便:

def your_action
  ...
  render :action => :index
end

【讨论】:

  • 我尝试使用 render :template 但正在渲染 html,我需要渲染 index 方法,因为 index 方法从 DB 获取该视图所需的一些数据。
  • fl00r 是对的,最好从控制器内部处理。请注意,有一个内置的回退,如果它找不到控制器/索引,它会呈现应用程序/索引。因此,如果有需要从不同控制器渲染的页面(不是部分页面),请将它们放在 app/views/application 下。
【解决方案2】:

这对我很有效:

def renderActionInOtherController(controller,action,params)
  controller.class_eval{
    def params=(params); @params = params end
    def params; @params end
  }
  c = controller.new
  c.request = @_request
  c.response = @_response
  c.params = params
  c.send(action)
  c.response.body
end

然后,调用

render :text => renderActionInOtherController(OtherController,:otherAction,params)

基本上它会破解另一个类并覆盖其“params”方法并返回

如果您使用的是 Rails 4:

def renderActionInOtherController(controller,action,params)
    c = controller.new
    c.params = params
    c.dispatch(action, request)
    c.response.body
end

【讨论】:

  • 这也适用于我,但我需要添加 c.process_action(action) 才能让我的 before_actions 触发。
  • 该死,这是一个巧妙的技巧。非常感谢!
【解决方案3】:

来自 Rails 指南page

将渲染与 :action 一起使用是 Rails 的常见混淆源 新人。指定的动作是 用于确定要查看的视图 渲染,但 Rails 不运行任何 该操作的代码 控制器。任何实例变量 您在视图中要求的必须是 设置在当前动作之前 调用渲染。

总之你不能渲染另一个动作,你只能渲染另一个模板。您可以获取共享代码并将其移动到应用程序控制器中的方法。如果您真的无法以其他方式构建代码,您也可以尝试以下方式:

# This is a hack, I'm not even sure that it will work and it will probably
# mess up your filters (like ignore them).
other_controller = OtherController.new
other_controller.request = @_request
other_controller.some_action

【讨论】:

    【解决方案4】:

    如果您不想仅仅渲染另一个控制器(/model)的view,而是调用action(方法),请多考虑红宝石的生活方式 - 将此方法放入module 并将其包含在您需要的控制器中。

    我认为它不那么“诡异”,然后以某种方式触摸另一个控制器。

    module StandardActions
        def show_user_homepage(local_params=params)
            #something finding 
            #something to check
            render :"homepage/show" 
        def
    end
    
    class AddressesController < ApplicationController
        include StandardActions
    
        def update
            # update address
            if ok
                show_user_homepage(id: user_id)
            else
                #errorthings
                render :edit #(eg.)
            end
        end         
    end
    
    class HobbiesController  < ApplicationController
        include StandardActions
    
        def update      
            # update hobby
            if ok
                show_user_homepage(id: user_id)
            else
                #errorthings
                render :edit #(eg.)
            end
        end         
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-28
      • 2012-03-07
      • 1970-01-01
      • 2011-06-02
      • 2016-02-03
      • 2012-06-04
      • 2018-04-18
      • 2015-10-25
      相关资源
      最近更新 更多