self.prepend_view_path - am I missing something

I have an app that varies its content based upon the domain from which
it is being accessed. Some of the domain characteristics are
supported in the model but it is easier varying static text in the
views and then sharing the form templates via partials etc.

Rails 2.3.10 and looking at the documentation at


before_filter :domain_lookup, :set_view_paths


  def set_view_paths
    self.prepend_view_path "app/views/#{controller_name}/

according to the documentation this should add this path to the front
of the search order for this request only (as opposed to the similar
class method which prepends for all future requests)

I would expect the template to be rendered for the controller from app/
views/quote/type1/new.html.erb if it exists, if it does not exist it
will fall back to app/views/quote/new.html.erb

When I GET http://domain1:3000/quote/new it always renders app/views/
quote/new.html.erb and in the log I can see

Processing QuoteController#new (for at 2011-02-21
18:47:52) [GET]
  Domain Load (0.2ms) SELECT * FROM "domains" WHERE
("domains"."host" = '') LIMIT 1
  Policy Load (0.2ms) SELECT * FROM "policies" WHERE
("policies"."id" = 6)
Rendering template within layouts/application
Rendering quote/new

which is incorrect.

In my development environment I also render a debug partial and in it
I have

<p><%= self.view_paths %></p>

which renders the pathset object.


Has anyone got this working? I was thinking of over-riding render but
am wary of any side effects.



Tada. Spending a bit of time in debugger and going through the Rails
code here is where it all happens:

So it goes hunting for load_path + template_path on line 60 where
load_path is iterated over view_path that I set in the application
controller and template path is "controller/action"

In an nutshell the view path is just the set of "roots" from which the
template_path (i.e. controller/action) is loaded as the template.

All I needed to do is change my directory structure for this:


  before_filter :domain_lookup, :set_view_paths


  def set_view_paths
    self.prepend_view_path ["app/views/variants/

and set out my view directories as follows:

app/views/controller_name becomes the fall-back or default set of
views if the variant of the view does not exist
app/views/variants/policy_type/controller_name is where you put all of
the variants of the view for the specific variant.

This approach does have a nice side-effct of allowing all of the
references to partials from within the view of also being loaded in
the same fashion. For example, if I want a variant of a form for one
of the domains, all I need to do is put the modified version of the
form partial in the appropriate directory and all the relative paths
to partials can remain the same. As they say. Neat.

All in all this is a nice technique for using the same application to
serve multiple variants (skins) based on domain or sub-domain name.

I did find similar postings trying to do the same thing. Either I and
they misread the documentation or it is not very clear how view_paths
evaluate to the actual filename. I'll look into putting in an
amendment to the documentation.


> def set_view_paths
> self.prepend_view_path "app/views/#{controller_name}/
> #...@domain.policy.policy_type}"
> end

Above worked in development but not in testing unless you provide an
absolute path for integration testing.

  def set_view_paths
    self.prepend_view_path ["#{RAILS_ROOT}/app/views/variants/