Multi-level hierarchy selections

I’m not sure what the best subject line for this is... I am trying to understand more about what parts of Rails have access to what information.

I have one type (Interest) organized into a self-referential hierarchy. A user can select any leaf node in that hierarchy. This is working fine.

I want to present the user with all of the levels in the hierarchy, however, despite recording only the leaf node ID. For an existing selection, he should see multiple drop-downs, one for each level of the hierarchy. For a new selection, he should see only the first level, with a new select widget created when he has selected a non-leaf node in the previous one.

Pointers to recipes or resources would be most welcome. I only need this to work in the editing interface (for which I am using formtastic); the show view can just display the leaf node.

Below are some relevant code snippets; the comment in _user_interest_fields.html.erb is where I want the change to manifest.

I think that I need (a) to create some pseudo-attributes for the user or interest to give the hierarchy, so that the view can act on them, but I’m not sure how to do this for arbitrary depth; and (b) to provide some JavaScript so that the view knows how to dynamically create new select lists for each hierarchy level. However, I’ve been thrashing around trying to figure out where to start, and would really love some pointers.

Thanks in advance, Chris

=-=-=-= app/models/interest.rb =-=-=-=

class Interest < ActiveRecord::Base   attr_accessible :name

  validates_presence_of :name   validates_uniqueness_of :name

  has_many :parent_relationships,     :class_name => "InterestParentage",     :foreign_key => :child_id,     :dependent => :destroy   has_many :parents,     :through => :parent_relationships,     :source => :parent

  has_many :child_relationships,     :class_name => "InterestParentage",     :foreign_key => :parent_id,     :dependent => :destroy   has_many :children,     :through => :child_relationships,     :source => :child end

=-=-=-= app/models/user_interest.rb =-=-=-=

class UserInterest < ActiveRecord::Base   attr_accessible :user_id, :interest_id

  validates_presence_of :user_id, :interest_id   validates_uniqueness_of :interest_id, :scope => :user_id

  belongs_to :user   belongs_to :interest end

=-=-=-= app/controllers/user_controller.rb =-=-=-=

  # GET /users/1/edit   def edit     @user = User.where(:user_id => current_user)   end

=-=-=-= app/views/users/_form.html.erb =-=-=-=

<%= semantic_form_for( @user ) do |f| %>   <fieldset class="input">     <legend>Interests</legend>     <%= f.semantic_fields_for :user_interests do |builder| %>       <%= render( 'user_interest_fields', f: builder ) %>     <% end %>     <p>       <%= link_to_add_fields(             "Add Interest",             f,             :user_interests           )       %>     </p>   </fieldset>   <div class="actions">     <%= f.submit %>   </div> <% end %>

=-=-=-= app/views/users/_user_interest_fields.html.erb =-=-=-=

<div class="user_interest">   <ul>     <!-- Currently, this lists *all* interests, regardless of          position in the hierarchy. It should be replaced by          multiple select lists, one for each hierarchy level. -->     <%=        f.input(          :interest,          :as => :select,          :collection => Interest.all.collect {            >s> [s.name, s.id]          },          :label => true        )     %>     <%= f.hidden_field :_destroy %>     <%=        link_to_remove_fields(        "remove",        :user_interests        )        %>   </ul> </div>

=-=-=-= end =-=-=-=