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,