3

Given Rails 4.2, Ruby 2.3.1.

In theory, Rails should allow you to completely reset the view paths, as seen here, in the source code.

However, when I reset the view_paths via #view_paths=, from a controller callback, something unexpected happens.

> view_paths.size
=> 2
> new_paths = view_paths.reject { |vp| rejection criteria }
> new_paths.size
=> 1
> view_paths = new_paths
> view_paths.size
=> 2
> _view_paths.size
=> 1

self._view_paths has successfully been reset, but #view_paths has not picked up those changes, despite simply being a wrapper for self._view_paths. Why is self._view_paths correct, and #view_paths not?

Note: This is important because Rails uses #view_paths when searching for view, not self._view_paths.

steel
  • 11,883
  • 7
  • 72
  • 109

2 Answers2

0

Try changing

view_paths = new_paths

to

self.view_paths = new_paths

view_paths = new_paths is most likely initializing a local variable called view_paths instead of calling the method view_paths=

Edit:

Since you are getting a NoMethodError you are not in the context you think you are in since there is a method with that name in the file you posted https://github.com/rails/rails/blob/ec28c4fb242a9bf0632bb4dac0d0a2d949eab1b3/actionpack/lib/abstract_controller/view_paths.rb#L91

kcdragon
  • 1,724
  • 1
  • 14
  • 23
  • `self.view_paths = new_paths` throws `NoMethodError: undefined method 'view_paths='` – steel Aug 16 '16 at 14:48
  • 1
    Then that should tell you that you are not in the context you think you are in since there is a method with that name in the file you posted https://github.com/rails/rails/blob/ec28c4fb242a9bf0632bb4dac0d0a2d949eab1b3/actionpack/lib/abstract_controller/view_paths.rb#L91. – kcdragon Aug 16 '16 at 14:57
  • Good call on the context. If you update your answer I can change my down to an upvote. (SO has locked me changing my vote) – steel Aug 16 '16 at 15:02
  • @steel if this solved your question, would you mind marking it as the answer. If not, let me know what you are missing. – kcdragon Aug 21 '16 at 14:04
  • The suggested answer throws an error. I was able to use another tack that I added as an answer. – steel Aug 22 '16 at 15:27
0

It looks like once a controller instance is created, the view path is accessed from the lookup_context, and that is where it needs to be changed.

 lookup_context.view_paths.paths.reject! { |vp| rejection criteria }
steel
  • 11,883
  • 7
  • 72
  • 109