Question

As much amazing info as is out there, it often seems to fall just short of my demented requirements. That said, I'm looking for a mechanism by which to handle multiple nested models on a single page.

Now, I've seen all the videos and posts (not really, but humor me) on nesting two models (Railscasts, etc.). However, I need to deal with models nested 4 deep, all the while using Javascript to keep the page clean.

Basically I have Site -> Buildings -> Controllers -> Measurements and would like to manage (CRUD) a complete site on a single page. I'm sure it's possible, but I have yet to see a reasonably clean method around which I can wrap my head. If anyone has any input, I'm all ears (or eyes as the case may be).

Thanks in advance.

Was it helpful?

Solution

Some skilled programmers recommend only nesting resources 1 level deep. Certainly your domain can be more complex, but you shouldn't expose all of that complexity in a single view. If you really need to manage an entire Site on a single page, I recommend you use multiple forms and update the various displays via AJAX, rather than trying to do it all in one form. You'll have better usability and cleaner code.

EDITED

Okay, here's a sample view in HAML:

%h1 Editing Site
#site-form
  - form_for @site, :class => 'remote', :'data-update' => '#site-form' do |f|
    %p
      = f.label :name
      = f.text_field :name
    %p
      [All the other fields on your Site model]
    %p
      = f.submit "Save Site"


%h2 
  Buildings for 
  = @site.name
#buildings-forms
  - for building in @site.buildings
    %div{ :id => "building-#{building.id}" }
      - form_for building, :class => 'remote', :'data-update' => "#building-#{building.id}" do |f|
        %p
          = f.label :name
          = f.text_field :name
        %p
          [All other building fields]
        %p
          = f.submit "Save Building"    
      %h3 
        Controllers for
        = building.name
        - for cntroller in building.controllers
          %div{ :id => "controller-#{cntroller.id}"}
            - form_for cntroller, :class => 'remote', :'data-update' => "#controller-#{cntroller.id}" do |f|
              %p
                = f.label :name
                = f.text_field :name
              %p
                [All other controller fields]
              %p
                = f.submit "Save Controller"

And the next level, Measurements, will look pretty much the same.

As far as getting the AJAX rocking, in jQuery you say:

$( function() {
  $('form.remote').submit( function() {
    var submitted_form = this;
    $.post( this.action, $.serialize(this), function( data_returned, status, request ) {
      var updated_block = $( data_returned ).find( $(submitted_form).attr('data-update').html();
      $( $(submitted_form).attr('data-update') ).html( updated_block );
    } );
    return false;
  } );

});

This allows each form to post and updates its updateable block with a new version from the server once a post has occurred. You can get fancier and use the metadata plugin to store info on which block should be updated and other info about the request, but this is simple and allows you to see the configuration in your html. data-x attributes are a scheduled feature of HTML5, but we can go ahead and use them anyway.

By creating a convention for your remote forms, it's easy to make jQuery handle all your ajax posts with a small amount of code. You'll probably want some fancier stuff, spinners, validations, etc. There's room for that, but this will get you started with a single page interface.

OTHER TIPS

Check out http://activescaffold.com/ and Streamlined -- http://streamlinedframework.org/ both support nested models on a page.

Note that you probably need some training for your users. A 4 level deep model is not something that people run into every day.

I think the simplest way would be to break it down in parent->child pairs:

  • Site->Building
  • Building->Controller
  • Controller->Measurement

Then you have a simple relationship between all 4.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top