如何更改 Rails 3 控制器中视图文件的默认路径?

Posted

技术标签:

【中文标题】如何更改 Rails 3 控制器中视图文件的默认路径?【英文标题】:How to change the default path of view files in a Rails 3 controller? 【发布时间】:2011-05-17 02:52:58 【问题描述】:

我有一个名为ProjectsController 的控制器。默认情况下,它的操作会在 app/views/projects 中查找视图。我想更改控制器中所有方法(indexshownewedit 等)的路径。

例如:

class ProjectsController < ApplicationController

  #I'd like to be able to do something like this
  views_path 'views/mycustomfolder'

  def index
    #some code
  end

  def show
    #some code
  end

  def new
    #some code
  end

  def edit
    #some code
  end
end

请注意,我不是用render 更改每个方法,而是为所有方法定义一个默认路径。这可能吗?如果有,怎么做?

谢谢!

【问题讨论】:

【参考方案1】:

见ActionView::ViewPaths::ClassMethods#prepend_view_path。

class ProjectsController < ApplicationController
    prepend_view_path 'app/views/mycustomfolder'
    ...

【讨论】:

这将在 'app/views/mycustomfolder/projects/' 中查找视图 命名空间控制器怎么样?如果我有一个 api/v3/todos_controller.rb,它将尝试在 app/view/mycustomfolder/api/v3/todos/show.json.rabl 而不是 app/view/mycustomfolder/todos/show.json 中查找模板.rabl 当前位置:edgeapi.rubyonrails.org/classes/ActionView/…(建议编辑队列已满)【参考方案2】:

您可以在控制器中执行此操作:

  def self.controller_path
    "mycustomfolder"
  end

【讨论】:

出色,完美运行,是目前为止这个问题的最佳解决方案。 这样做可行,但除非我指定 use_route,否则我的 RSpec 控制器测试不会使用正确的控制器,现在 Rails 4 中已弃用。 有效但破坏了控制器规范 有谁知道控制器规范的问题是此代码失败还是控制器规范工作方式失败?我不知道如何回答这个问题,但我认为无论控制器是如何使用的,这样做都应该始终有效。也许我错了。【参考方案3】:

如果没有为此的内置方法,也许您可​​以覆盖该控制器的render

class MyController < ApplicationController
  # actions ..

  private

  def render(*args)
    options = args.extract_options!
    options[:template] = "/mycustomfolder/#params[:action]"
    super(*(args << options))
  end
end

不确定这在实践中效果如何,或者是否完全有效。

【讨论】:

这实际上工作得很好,除了action 变量不存在。但是,这与需求无关(我只需要在路径前添加一个文件夹)。非常感谢! prepend_view_path 是更清洁的解决方案。【参考方案4】:

您可以添加如下内容:

paths.app.views << "app/views/myspecialdir"

在 config/application.rb 文件中让 rails 在另一个目录中查找视图模板。需要注意的是,它仍然会寻找与控制器匹配的视图文件。因此,如果您有一个名为 HomeController 的控制器,它具有上述视图配置,它将查找名为“app/views/myspecialdir/home/index.html.erb”的内容来呈现。

【讨论】:

这看起来很直观,但实际上会导致以下错误:'undefined local variable or method `paths' for ApplicationController:Class' - 有什么想法吗? 您使用的是什么版本的导轨?我已经在 rails 3.0.x 中尝试过,在 config/application.rb 的类 Application 作为记录,我认为path.app.views.unshift("views/myspecialdir") 会起作用。 IE。将您自己的特殊条目添加到数组的开头,而不是在末尾追加。 Rails 可能会从数组的开头查找匹配项。 以上内容对我不起作用,但确实如此:paths['app/views'] &lt;&lt; "app/views/myspecialdir"【参考方案5】:

如果您想在应用级别更改所有视图的默认路径,您可以执行以下操作 -

class ApplicationController < ActionController::Base
  before_action :set_views

  private

  def set_views
    prepend_view_path "#Rails.root.join('app', 'views', 'new_views')"
  end
end

并按照与原始目录结构相同的目录结构将所有视图写入文件夹new_views

附: - 这个答案的灵感来自@mmell的答案。

【讨论】:

【参考方案6】:

接受的答案不再对我有用。经过多次哀嚎和咬牙切齿,我设法发现如果在操作中没有调用render,那么就会调用default_render 方法。就我而言,我需要覆盖控制器中的default_render 消息,如下所示:

def default_render
  render "path/to/views/#action_name.to_s"
end

【讨论】:

以上是关于如何更改 Rails 3 控制器中视图文件的默认路径?的主要内容,如果未能解决你的问题,请参考以下文章

更改 Rails 中的默认视图路径?

如何更改默认设计视图路径?

如何更改默认的Laravel Auth登录视图

Rails 3.1 资产管道:如何加载特定于控制器的脚本?

如何在rails的js中更改视图变量

Rails:允许用户在注册时选择他们的角色设计