soldiershin
soldiershin

Reputation: 1620

Using ancestry gem to create parent-child-grandchild relationship in ruby

I have trying to get a hang of ancestry gem for the past two days.I have checked one/two tutorials but they are old and have alot of mistakes or do not work.I have been able to get a hold of a little of ancestry but i want some help on how to properly define parents,children,root and grandchildren.I have read the documentation but i can't get a proper hand of it.The flow of my project is.

----Parent1

------Child1

---------Grandchild1

------Child2

----Parent2

------Child1

Now i have gotten ahold of how to create a parent ID.This is my code.

  def index
 @messages = Message.all
 end

 def show
    @page = Message.where(:ancestry => params[:id])
  end

  def new
    @message_id = Message.find(params[:id])
  end

 def create
    @page = Message.new(message_params)
    @page.parent_id = params[:parent_id]
   #@page = Message.new(message_params)

     if @page.save
        flash[:notice] = "The Mesage was created succeffully"
       redirect_to(:action => 'index')
    else
      render('new')
  end
end

This is the index file which displays the data and can also post messsages.

<div class="Pages index">
   <h2>Messages</h2>

   <%= link_to("Add new Page",{:action => 'new'}, :class => 'action new') %>

     <table class="listing" summary="Page list">
       <tr class="header">
          <th>&nbsp;</th>
          <th>ID</th>
          <th>Content Title</th>
          <th>Content</th>
          <th>Parent Id</th>
       </tr>

       <% @messages.each do |page| %>
       <tr>
          <td><%= page.id %>
          <td><%= page.content_title %>
          <td class="center"><%= page.content %>
          <td class="center"><%= page.parent_id %>

          <td class="actions">
             <%= link_to("Reply",{:action => 'new',:id => page.id},:class =>'action show') %>
             <%= link_to("Show",{:action => 'show',:id => page.id},:class =>'action show') %>        

          </td>
        </tr>
        <% end %>
        </table>
        </div> 

        <div class="Pages new">
   <h2> Create Pages</h2>
     <%= form_for(:message, :url => {:action => 'create'}) do |f| %>
     <table summary="Page form fields">

        <tr>
          <th>Content_title</th>
          <td><%= f.text_field(:content_title) %></th>
        </tr>
        <tr>
          <th>Content</th>
          <td><%= f.text_field(:content) %></th>
        </tr>
        </table>

        <div class="form-buttons">
          <%= submit_tag("Submit Form") %>
          </div>

          <% end %>
        </div>

This is the reply file which when user presses the reply button passes the parent_id

<div class="Pages new">
   <h2> Create Pages</h2>
     <%= form_for(:message, :url => {:action => 'create',:parent_id => @message_id}) do |f| %>
     <table summary="Page form fields">
     <tr>
          <th>ParentID</th>
          <td><%= f.text_field(:id) %></th>
        </tr>
        <tr>
        <tr>
          <th>Content Title</th>
          <td><%= f.text_field(:content_title) %></th>
        </tr>
        <tr>
          <th>Content</th>
          <td><%= f.text_field(:content) %></th>
        </tr>
        </table>

        <div class="form-buttons">
          <%= submit_tag("Submit Form") %>
          </div>

          <% end %>
        </div>   

Heres the show file

<%= link_to("Back to List",{:action => 'index'}, :class => 'action new') %>

<div class="Pages show">
   <h2> Show Pages</h2>

     <table summary="Pages detail view">
          <th>Parent ID</th>
        </tr>
        <tr>
          <th>Message Content Title</th>
        </tr>
        <tr>
          <th>Content</th>
        </tr>
        <% @page.each do |page| %>
       <tr>
          <td><%= page.id %>
          <td><%= page.content_title %>
          <td class="center"><%= page.content %>
          <td class="center"><%= page.parent_id %>
         </td>
         </td>
         </td>
         </td>
         </tr>
         <%end%>
         </table>

Now this was simple but how do i select the root and child of the node and how to display them accordingly. I have tried rails console to get an idea but there's another issue.For example If a parent contains multiple child it displays the result but if a child contains children it doesn't show anything although when a parent child are displayed all its grandchildren also get displayed.I m bit confused by this.Any help is appreciated

Upvotes: 0

Views: 2894

Answers (1)

lcguida
lcguida

Reputation: 3847

For what I see, I don't think you do understand the Tree Data Structure.

I recommend reading this: http://en.wikipedia.org/wiki/Tree_(data_structure)

For you example, you have the following tree:

-parent 1
 -child 1.1 (parent -> parent 1)
 -child 1.2 (parent -> parent 1)
 -granddchild 1.2.1 (parent -> child 1.2)
-parent 2
 -child 2.1

So in this example parent 1 and 2 are root nodes (they don't have a parent). child 1.1 and 1.2 (are children of parent 1). So if you want to access them you should do:

parent1.children

grandchild1.2.1 is child of node child1.2 and it's grandchild of node parent1.

To get all of the, from parent1, you should ask for the descendants:

parent1.descendants

Siblings are nodes with the same parent, for example child 1.2 and child 1.1.

Example of use: You have child1.1, and you want it's siblings (brothers). Instead of doing

child1.1.parent.children

You would do:

child1.1.siblings

These are just some examples, but in order to fully comprehend the methods available in the ancestry gem, you really should study and understand the Tree Data Structure

Upvotes: 1

Related Questions