Is there a Rails3 way to "scope" views?

I am finding my views directory a bit cluttered and I would like to move some related views into their own subdirectory under app/views. Is there a Rails way to specify that app/views/** should be searched in addition to app/views?

You can set view_paths on controller.

James Byrne wrote in post #957825:

I am finding my views directory a bit cluttered and I would like to move some related views into their own subdirectory under app/views. Is there a Rails way to specify that app/views/** should be searched in addition to app/views?

As Robert said, you can certainly do this.

But why? What does your views directory look like now? Where's the clutter? In my experience, views directories generally don't get that cluttered, so I'm wondering if something strange is happening with your design...

Best,

To me, having several hundred files in a single directory is cluttered. Others have different thresholds of tolerance. Mine is low.

In any case, once given the hint above I managed to locate some information on ActonController.config.view_paths. Not enough to actually try anything just yet, but the leads are promising.

Please quote when replying.

James Byrne wrote in post #957905:

To me, having several hundred files in a single directory is cluttered.

To me too -- if we're talking *files*. But again: that should never happen. Let's see your views and controllers. I suspect you are trying to cram too much into a single controller, and ending up with lots of actions and views as a result.

I think several hundred *directories* in a single directory, OTOH, is no problem at all.

Best,

Marnen Laibow-Koser wrote in post #957913:

To me too -- if we're talking *files*. But again: that should never happen. Let's see your views and controllers. I suspect you are trying to cram too much into a single controller, and ending up with lots of actions and views as a result.

I mis-wrote. As you picked up I really meant view directories. But, why should it never happen for view directories?

I am writing an application that handles international freight bookings, movements and customs formalities including edi cusdec transmissions. That is never ever going to fit into a handful of controllers. In fact, but for foreign exchange, most controllers possess only the basic index, show, new, create, and destroy actions. Many do not have all of these.

A sample controller, one of the more complex ones, is given below:

class CustomsShipmentParsChecksController < ApplicationController

  skip_before_filter :authenticated   skip_before_filter :authorised

  # POST /collection   # POST /collection.xml   def create

    respond_to do |format|       if @manifest = CaCustomsManifest.find_by_ccdn(             params[:ca_customs_manifest][:ccdn].strip)

        @shipment = @manifest.ca_customs_shipment         @entry = @shipment.ca_customs_entry

        if @manifest.ca_customs_shipment.ca_customs_entry.is_across_accepted           flash[:info] = accepted_message           # render simply uses the template specified by the :action key           # without calling the method.           format.html { render :action => "show" }           format.xml { render :xml => @shipment,                                 :status => :accepted,                                 :location => :customs_shipment_pars_check }         else           flash[:notice] = not_accepted_message           format.html { render :action => "show", :id => @shipment.id }           format.xml { render :xml => @manifest,                                 :status => :found,                                 :location => :customs_shipment_pars_check }         end       else         new # build a dummy record complex to allow display of messages         manifest.ccdn = params[:ca_customs_manifest][:ccdn].strip         flash[:notice] = not_found_message         flash[:warn] = contact_message         format.html { render :action => "new" }         format.xml { render :xml => @manifest.errors,                               :status => :not_found }       end     end   end

  # DELETE /collection/:id   # DELETE /collection/:id.xml   def delete     show   end

  # Do not raise pointless not found errors   # GET /collection/:id/edit   def edit     show   end

  # GET /collection/new   # GET /collection/new.xml   def new     @shipment = CaCustomsShipment.new     @entry = @shipment.build_ca_customs_entry     @manifest = @shipment.ca_customs_manifests.build   end

  # GET /collection   # GET /collection.xml   def index     new   end

  # GET /collection/:id   # GET /collection/:id.xml   def show     get_shipment   end

private ...

end

Not sure if it's possible in your architecture, but we are working a lot with namespaces. E.g. you could have a Customs::ShipmentParsChecksController and a Customs::SomeOtherController etc. this would group your controllers, models and views into related sections. Your views then would look like: app - views   - customs    + shipment_pars_checks    + some_other

Best, Daniel

Daniel Guettler wrote in post #957936:

Not sure if it's possible in your architecture, but we are working a lot with namespaces. E.g. you could have a Customs::ShipmentParsChecksController and a Customs::SomeOtherController etc. this would group your controllers, models and views into related sections. Your views then would look like: app - views   - customs    + shipment_pars_checks    + some_other

Best, Daniel

Thanks. I will look into this. I have not worked with namespaces so I never thought of that approach.

James Byrne wrote in post #957930:

Marnen Laibow-Koser wrote in post #957913:

To me too -- if we're talking *files*. But again: that should never happen. Let's see your views and controllers. I suspect you are trying to cram too much into a single controller, and ending up with lots of actions and views as a result.

I mis-wrote. As you picked up I really meant view directories. But, why should it never happen for view directories?

Why should *what* never happen? That you should have lots of view directories? I specifically didn't say that that should never happen.

I am writing an application that handles international freight bookings, movements and customs formalities including edi cusdec transmissions. That is never ever going to fit into a handful of controllers.

Of course it won't. I didn't mean to suggest that it would. In fact, I was suggesting more controllers, not fewer.

If you don't like the number of controllers, group them in namespaces.

In fact, but for foreign exchange, most controllers possess only the basic index, show, new, create, and destroy actions. Many do not have all of these.

A sample controller, one of the more complex ones, is given below:

class CustomsShipmentParsChecksController < ApplicationController

  skip_before_filter :authenticated   skip_before_filter :authorised

  # POST /collection   # POST /collection.xml   def create

    respond_to do |format|       if @manifest = CaCustomsManifest.find_by_ccdn(             params[:ca_customs_manifest][:ccdn].strip)

        @shipment = @manifest.ca_customs_shipment         @entry = @shipment.ca_customs_entry

        if @manifest.ca_customs_shipment.ca_customs_entry.is_across_accepted           flash[:info] = accepted_message           # render simply uses the template specified by the :action key           # without calling the method.           format.html { render :action => "show" }           format.xml { render :xml => @shipment,                                 :status => :accepted,                                 :location => :customs_shipment_pars_check }         else           flash[:notice] = not_accepted_message           format.html { render :action => "show", :id => @shipment.id }           format.xml { render :xml => @manifest,                                 :status => :found,                                 :location => :customs_shipment_pars_check }         end       else         new # build a dummy record complex to allow display of messages         manifest.ccdn = params[:ca_customs_manifest][:ccdn].strip         flash[:notice] = not_found_message         flash[:warn] = contact_message         format.html { render :action => "new" }         format.xml { render :xml => @manifest.errors,                               :status => :not_found }       end     end   end

Too long. Most of that should be refactored into model methods. Remember, "skinny controller, fat model". A controller method over 5-10 lines is a sure sign that you need to do more refactoring.

Best,