Ruby-on-Rails
  Home arrow Ruby-on-Rails arrow Page 3 - Delving Deeper into the Active Record with...
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Moblin 
JMSL Numerical Library 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
RUBY-ON-RAILS

Delving Deeper into the Active Record with Ruby-on-Rails
By: A.P.Rajshekhar
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 2
    2006-11-28

    Table of Contents:
  • Delving Deeper into the Active Record with Ruby-on-Rails
  • Relationship Mapping
  • Acts As Mapping
  • Mapping and Rails in the Real World

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Delving Deeper into the Active Record with Ruby-on-Rails - Acts As Mapping


    (Page 3 of 4 )

    The Relationship Mapping previously discussed provides mapping that is in one-to-one correspondence with the underlying database. In most cases, such a mapping is all that is required. However, this is simple in terms of variation in data structures. There are situations where data may be required to be presented in a different way. This is where Acts As Mapping plays a key role.

    Acts As Mapping is built on top of a has_  relationship. Active Record provides two types of  Acts As Mapping: Acts As List and Acts As Tree. As the name suggests the former provides List data structure and the later provides Tree data structure.

    Acts As List

    In a has_ relationship, if acts_as_list is declared in a class representing a child (the many end of the one-to-many relationship), the class representing the parent can view the child like a list. In other words, it gives the child list-like behavior. It facilitates the parent to traverse the children around in a list as well as remove the children from the list.

    To implement such a behavior, the child table needs a column called position. Here again convention takes precedence. If the column is named position, Active Record will automatically use it. Active Record uses this column to record the position of the child. An example will make the concept more clear. For brevity I will be using tables named PARENTS and CHILDREN. Here are the DDL:

     

    create table parents (

    id int not null auto_increment,

    primary key (id)

    );

    create table children (

    id int not null auto_increment,

    parent_id int not null,

    name varchar(20),

    position int,

    constraint fk_parent foreign key (parent_id) references parents(id),

    primary key (id)

    );

      

    The following are the corresponding classes:

     

    class Parent < ActiveRecord::Base

    has_many :children, :order => :position

    end

     

    class Child < ActiveRecord::Base

    belongs_to :parent

    acts_as_list :scope => :parent_id

    end

                   

    The Parent class has one extra argument to the has_many declaration:  :order. It ensures that the array is fetched from the database in the correct order. In the Child class, acts_as_list is declared and the scope is that of the parent_id or  in other words, ensures that the children are placed in the corresponding parent's list instead of a global list. Now let's set up some test data - three children named One, Two and Three for a parent as follows:

     

    parent = Parent.new

    %w{ One Two Three}.each do |name|

    parent.children.create(:name => name)

    end

    parent.save

     

    The following statements show how the children display behavior akin to that of a list:

     

    #A simple method to let us examine the contents of the list.

     

    def display_children(parent)

    puts parent.children.map {|child| child.name }.join(", ")

    end

     

    display_children(parent) #=> One, Two, Three, Four

    puts parent.children[0].first? #=> true

     

    two = parent.children[1]

    puts two.lower_item.name #=> Three

    puts two.higher_item.name #=> One

     

    parent.children[0].move_lower

    parent.reload

    display_children(parent) #=> Two, One, Three, Four

    parent.children[2].move_to_top

    parent.reload

    display_children(parent) #=>

     

    The various move operations update the position. The parent must know this change immediately, hence the reload operation is called after the move_lower or move_higher operation.

    Acts As Tree

    The other kind of data structure that is commonly used is Tree. There are scenarios where the rows of a table need to be represented in the form of a tree structure. For this Active Record provides the Acts As Tree mapping. To use this, the corresponding table needs to have one additional column -- parent_id  -- which is a foreign key reference back into the same table, linking child rows to their parent row. The pictorial representation would be as follows:

     

     

    The best example of such a scenario is the previously discussed CATEGORIES table. Each category may have a sub-category and each sub-category may have its own sub-category. To make matters simple, let's create a CATEGORIES table having id, name and parent_id. So here is the DDL:

     

    create table categories (

    id int not null auto_increment,

    name varchar(100) not null,

    parent_id int,

    constraint fk_category foreign key (parent_id) references categories(id),

    primary key (id)

    );

     

    Next, in the corresponding class, the declaration acts_as_tree has to be declared.

     

    class Category < ActiveRecord::Base

    acts_as_tree :order => "name"

    end

     

    The parameter :order tells the framework that the children of a particular node must be displayed according to the value of the name column. The following statements set up the test data as one would populate a tree:

     

    root = Category.create(:name => "Books")

    fiction = root.children.create(:name => "Fiction")

    non_fiction = root.children.create(:name => "Non Fiction")

    non_fiction.children.create(:name => "Computers")

    non_fiction.children.create(:name => "Science")

    non_fiction.children.create(:name => "Art History")

    fiction.children.create(:name => "Mystery")

    fiction.children.create(:name => "Romance")

    fiction.children.create(:name => "Science Fiction")

     

    Now let's see how to access the data:

     

    display_children(root) # Fiction, Non Fiction

    sub_category = root.children.first

    puts sub_category.children.size #=> 3

    display_children(sub_category) #=> Mystery, Romance, Science Fiction

    non_fiction = root.children.find(:first, :conditions => "name = 'Non Fiction'")

    display_children(non_fiction) #=> Art History, Computers, Science

    puts non_fiction.parent.name #=> Books

     

    Here I have used the display function created previously. So creating a tree structure using application code cannot get any simpler than this.

    That brings us to the end of this section. In the next section I will develop an application that utilizes the types of mapping just discussed.

    More Ruby-on-Rails Articles
    More By A.P.Rajshekhar


       · In this discussion I have focussed on the advanced mapping techniques in Active...
       · I think the first sentence of the last paragraph should read asIn the above...
     

    RUBY-ON-RAILS ARTICLES

    - Iterating and Incrementing Strings in Ruby
    - Comparing and Manipulating Strings in Ruby
    - Strings in Ruby
    - Ruby On Rails: Making Your First Dynamic Site
    - Ruby on Rails: Beginning Rails
    - Ruby: Modules, Mixins, Fixins, and Rails
    - Controlling Information Access with the Rail...
    - URLs, Filters and the Rails Action Controller
    - Flash and the Rails Action Controller
    - Rails Action Controller
    - Dropping and Sorting with AJAX and script.ac...
    - Drag and Drop with script.aculo.us and Rails
    - Introducing script.aculo.us
    - Ruby Classes and Objects
    - Ruby Loops






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway
    Stay green...Green IT