【问题标题】:How to change the default path of view files in a Rails 3 controller?如何更改 Rails 3 控制器中视图文件的默认路径?
【发布时间】: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 更改每个方法,而是为所有方法定义一个默认路径。这可能吗?如果有,怎么做?

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby model-view-controller ruby-on-rails-3


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        • 2011-04-25
        • 2021-11-26
        相关资源
        最近更新 更多