Home arrow Ruby-on-Rails arrow Page 2 - Delving Deeper into the Active Record with Ruby-on-Rails
RUBY-ON-RAILS

Delving Deeper into the Active Record with Ruby-on-Rails


In addition to allowing on-the-fly schema mapping, the Active Record provides a variety of services helpful to complicated table situations. Keep reading to learn more.

Author Info:
By: A.P.Rajshekhar
Rating: 5 stars5 stars5 stars5 stars5 stars / 6
November 28, 2006
TABLE OF CONTENTS:
  1. · Delving Deeper into the Active Record with Ruby-on-Rails
  2. · Relationship Mapping
  3. · Acts As Mapping
  4. · Mapping and Rails in the Real World

print this article
SEARCH DEVARTICLES

Delving Deeper into the Active Record with Ruby-on-Rails - Relationship Mapping
(Page 2 of 4 )

In real world applications, tables never exist in isolation. They are related at the database level using relationships based on the foreign key concept. One table can be related to another table through one-to-one, one-to-many or many-to-one relationships. Active Record bases its object-to-object relationship on how the corresponding tables are related at the database level. On the basis of types of database level relationships, there are three types of basic mapping in Active Record:

  • One-to-one Mapping
  • One-to-many Mapping
  • Many-to-many Mapping

Each of these are mapped using two-way mapping. That means the classes on both sides of relationships know how they are related to the other class.

In one-to-one mapping, a foreign key in one row of a table references at most a single row of another table. For example, let's take two tables - INVOICES and ORDERS. The following diagram shows the relation between the tables:

To map tables with a one-to-one relationship, Active Record provides two declarations that have to be added to the corresponding classes. They are  belongs_to and has_one. The belongs_to declaration appears in the class/model for the table that contains the foreign key, whereas has_one is declared in the class which is on the other end i.e. the one whose primary key is acting as the foreign key. To map the classes according to the relationship between INVOICES and ORDERS, the addition to the classes would be:

class Order < ActiveRecord::Base

has_one :invoice

. . .

class Invoice < ActiveRecord::Base

belongs_to :order

Since for each Order there is at most one Invoice, the Order class contains the has_one declaration connecting it to the object of the Invoice class. Similarly, the Invoice class contains the belongs_to declaration to map it with the Order class, more specifically the object of Order class.  

In a One-to-many relationship, a primary key in one row of a table references or is associated with an arbitrary number of rows in another table. For example, the relationship between ORDERS and LINE_ITEMS is that of one-to-many. The DDL of the tables will make it more clear:

DDL for ORDERS

create table orders (

id int not null auto_increment,

name varchar(100) not null,

/* ... */

primary key (id)

);

DDL for LINE_ITEMS

create table line_items (

id int not null auto_increment,

order_id int not null,

quantity int not null default 0,

unit_price float(10,2) not null,

constraint fk_items_order foreign key (order_id) references orders(id),

primary key (id)

);

         

An order can be associated with any number of line-items. To map such a relationship, one must use the declarations has_many and belongs_to. The declaration has_many must be declared in the class representing the table at the "one" end of a one-to-many relationship, whereas belongs_to is declared in the class representing the table at the "many" end of the relationship. To illustrate further, below are the classes corresponding to the ORDERS and LINE_ITEMS tables with the mapping declaration embedded:

class Order < ActiveRecord::Base

has_many :line_items

. . .

class LineItem < ActiveRecord::Base

belongs_to :order

Using the has_many declaration, the Order class is associated with the line_items class and tells the framework that one instance/object of the Order class is associated with many instances of the Line_Items class. The belongs_to declaration works in the same way as it works in one-to-one relationship mapping.

When many records of one table are associated with many records of another table, then the tables have a many-to-many relationship. To implement such a relationship, a link/join table needs to be used. The join table contains a foreign key for each of the tables its linking, so each row in the join table represents a linkage between the two tables. For example, PRODUCT and CATEGORIES have a many-to-many relationship. To implement the relationship, a link table has to be introduced: CATEGORIES_PRODUCT. It contains foreign key references to both tables. Here are the DDL of all three tables:

DDL for PRODUCTS

create table products (

id int not null auto_increment,

title varchar(100) not null,

/* . . . */

primary key (id)

);

 

DDL for CATEGORIES

 

create table categories (

id int not null auto_increment,

name varchar(100) not null,

/* ... */

primary key (id)

);

DDL for CATEGORIES_PRODUCTS

create table categories_products (

product_id int not null,

category_id int not null,

constraint fk_cp_product foreign key (product_id) references products(id),

constraint fk_cp_category foreign key (category_id) references categories(id)

);

The conventional way of mapping a many-to-many relationship would contain a declaration for the join/link table too. But that is not done with Active Record. Only the main tables are required to be mapped. It assumes that the join table is named after the two tables it joins (with the names in alphabetical order). To map the main tables, the classes corresponding to them must have the following declaration: has_and_belongs_to_many. This declaration links them both through the join/link table which is taken care by the Active Record.

 

class Product < ActiveRecord::Base

has_and_belongs_to_many :categories

. . .

class Category < ActiveRecord::Base

has_and_belongs_to_many :products

 

In the above example there is a mention of the link/join table. The reason is that once Active Record sees the declaration has_and_belongs_to_many in both  tables, it checks for the link table categories_products automatically. Thus "Convention-over-Configuration" works here too.


blog comments powered by Disqus
RUBY-ON-RAILS ARTICLES

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials