2

控制器中的此代码

av = ActionView::Base.new(Rails::Configuration.new.view_path)
av.extend ApplicationHelper
content = av.render(:file => "show", :locals => { :user => @user })

和 show.html.erb 有link_to帮助,操作代码错误

undefined method `url_for' for nil:NilClass

av.extend ActionController::UrlWriter在控制器中添加,仍然错误

undefined method `default_url_options' for ActionView::Base:Class
4

3 回答 3

2

尝试:

content = render_to_string(:file => "show", :locals => { :user => @user })
于 2013-01-17T15:03:57.183 回答
0

通常,在 Rails 中,当某些事情非常困难时,是因为您没有从理想的角度解决问题。除了建议不要这样做之外,我无法直接回答这个问题。理想情况下,视图逻辑应该在视图中,而不是控制器中。除了一些罕见的例外,比如在 flash 消息中使用 link_to 助手(这很容易解决),这些问题应该分开。这似乎不是这些例外之一。相反,我会推荐以下技术之一(稍微多一点 Rails-y):

选项1:

看起来您正在尝试为显示操作呈现视图。这可以通过使用render :action => 'show'( docs ) 轻松完成。这不会运行该操作的代码,只需使用该视图。

选项 2

如果选项 1 在您的情况下不可行,您也可以考虑以下技术的一些变体。照常渲染默认视图。将视图的现有内容移动到部分中,并将新内容移动到它自己的部分中。然后在您的视图中,只需根据适当的条件(@user 的存在)切换部分以呈现,例如:render :partial => @user ? 'new_content' : 'existing_content'. 根据您的应用程序结构,这可能可以通过仅从您的显示视图和问题中引用的操作的视图呈现相同的部分来进一步简化。

我认为将应用程序的各种元素隔离到它们的预期关注点中,不仅通过遵循最小惊讶原则更容易开发和维护,而且通常也使应用程序更容易测试。很抱歉没有回答您的问题 - 无论如何希望这会有所帮助。

于 2014-04-03T07:16:25.463 回答
0

我想它被称为外部控制器,所以我在 Rails 3 中这样做:

av = ActionView::Base.new(Rails.configuration.paths["app/views"])
av.class_eval do
  include ApplicationHelper
  include Rails.application.routes.url_helpers
  default_url_options[:host] = 'yoursite.com'
  def protect_against_forgery?
    false
  end
end
@result = av.render(:file => "show", :locals => { :user => @user })
于 2014-04-03T21:06:54.530 回答