How to change the default path of view files in a Rails 3 controller?

25,955

Solution 1

If there's no built-in method for this, perhaps you can override render for that controller?

class MyController < ApplicationController
  # actions ..

  private

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

Not sure how well this works out in practice, or if it works at all.

Solution 2

See ActionView::ViewPaths::ClassMethods#prepend_view_path.

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

Solution 3

You can do this inside your controller:

  def self.controller_path
    "mycustomfolder"
  end

Solution 4

You can add something like:

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

in the config/application.rb file to have rails look in another directory for view templates. The one caveat is that it'll still look for view files that match the controller. So if you have a controller named HomeController with the above config for the views it'll look for something named "app/views/myspecialdir/home/index.html.erb" to render.

Solution 5

If you want to change the default path for all your views at app level, you could do something like following -

class ApplicationController < ActionController::Base
  before_action :set_views

  private

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

And write all your views in the folder new_views following the same directory structure as original.

P.S. - This answer is inspired from @mmell's answer.

Share:
25,955

Related videos on Youtube

Yuval Karmi
Author by

Yuval Karmi

Updated on June 04, 2021

Comments

  • Yuval Karmi
    Yuval Karmi almost 3 years

    I have a controller called ProjectsController. Its actions, by default, look for views inside app/views/projects. I'd like to change that path for all methods (index, show, new, edit etc...) in the controller.

    For example:

    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
    

    Please note I am not changing each method with render but defining a default path for all of them. Is this possible? If so, how?

    Thank you!

  • Yuval Karmi
    Yuval Karmi over 13 years
    this seems intuitive, but it actually results in the following error: 'undefined local variable or method `paths' for ApplicationController:Class' - any ideas?
  • Yuval Karmi
    Yuval Karmi over 13 years
    this actually works perfectly, with the exception that the action variable does not exist. However, that was not relevant for needs (i just needed to prepend a folder to the path). thank you very much!
  • Mike Gorski
    Mike Gorski over 13 years
    What version of rails are you using? I've tried this in rails 3.0.x adding this line within the class Application < Rails::Application block in the config/application.rb with no issues.
  • Bushra Khan
    Bushra Khan over 13 years
    For the record, I assume path.app.views.unshift("views/myspecialdir") would work. I.e. add your own special entry to the beginning of the array instead of appending at the end. Rails probably looks up matches from the beginning of the array.
  • Ross
    Ross over 11 years
    That will look for views in 'app/views/mycustomfolder/projects/'
  • Matt Smith
    Matt Smith over 10 years
    prepend_view_path is much cleaner solution.
  • dvdplm
    dvdplm over 9 years
    Splendid, works perfectly and is imo by far the best solution to this problem.
  • Sarah Vessels
    Sarah Vessels almost 9 years
    Doing this works, but makes my RSpec controller tests not use the right controller unless I specify use_route, which is now deprecated in Rails 4.
  • makhan
    makhan over 8 years
    The above didn't work for me but this did: paths['app/views'] << "app/views/myspecialdir"
  • prikha
    prikha over 8 years
    Works but wrecks controller spec
  • Ten Bitcomb
    Ten Bitcomb almost 8 years
    Does anyone know if the problem with controller specs is a failing of this code or a failing of the way that controller specs work? I don't know how to answer that question, but I would think that doing this should always work regardless of how a controller is being used. Maybe I'm wrong.
  • Nik So
    Nik So about 7 years
    how about namespaced controllers? if I had a api/v3/todos_controller.rb, it will try to look up templates at app/view/mycustomfolder/api/v3/todos/show.json.rabl instead of app/view/mycustomfolder/todos/show.json.rabl
  • Dimitrios Mistriotis
    Dimitrios Mistriotis almost 7 years
    Current location: edgeapi.rubyonrails.org/classes/ActionView/… (Suggested edit queue is full)