Thursday, February 7, 2008

Eager loading with cascaded associations

Finder Methods, Eager loading with cascaded associations


Cascading association in rails is a wonderful development which allows you to use the Model Associations very easily and comfortably. Here with i will be explaining few techniques to use that:

Normal find method in rails is like this,

Author.find(:all)

With conditions,

Author.find(:all, :conditions => ".....")

Now let us suppose we are having a relation between a author and book, like an Author has many books and Book belongs_to author

To find books written by a particular Author, we will use some thing like

Author.find(:all, :include => :books)

Author.find(:all,:include => [:books,:novels]) if at all we are having association with the novels table also and if we want to retrieve the novels too.


But here comes the new area which i am about to tell you specifically.

That is if we are having a relation between Table A and Table B. Another relation between Table B and Table C.
But in one finder method if we wish to find the table C's content, querying through Table A, it is not possible. So we will be using cascading associations at this situation:

Starting from scratch,

:include Option recognizes the following options

Symbol - Base table simply Joins it.
Eg: Author.find(:all, :include=>:books)

String - Same as Symbol
Eg: Author.find(:all, :include => "books")

Array - The Base table joins those elements directly
Eg: Author.find(:all,:include=>[:books,:novels,:magazines])

Hash - The base table JOINS the KEY part and it JOINS the VALUE part.(Here value is processed as same as the :include option)
Eg: Author.find(:all,:include=>{:books,:movies})

Now i will explain about the depth of such kind of joining tables. Well , to say, that is not limited.As of now, i will explain uptil 2 and +2 methods

Normal with one association: One level deep
Author.find(:all, :include=>:posts)
=> authors
+ posts

Normal with two associations: One level deep

Author.find(:all, :include=>[:posts, :categorizations])
=> authors
+- posts
+- categorizations

Cascading Associations with two levels

Author.find(:all, :include=>[{:posts=>:comments}, :categorizations])
=> authors
+- posts
+- comments
+- categorizations

Author
.find(:all, :include=>{:posts=>[:comments, :categorizations]})
=> authors
+- posts
+- comments
+- categorizations

Cascading associations with more than two levels....

cascaded in three levels
>> Company.find(:all, :include=>{:groups=>{:members=>:favorites}})
=> companies
+- groups
+- members
+- favorites


>> Author.find(:all, :include=>{:posts=>{:author=>{:posts=>...}}})
=> authors
+- posts
+- author
+- posts
+- ...


It also has a feature that automatically aliases table name when conflicted. So we can use eager loading on same table names such as acts_as_tree.

TreeMixin.find(:all, :include=>"children")
=> mixins
+- children




1 comment:

Vinho said...

Hello. This post is likeable, and your blog is very interesting, congratulations :-). I will add in my blogroll =). If possible gives a last there on my blog, it is about the Vinho, I hope you enjoy. The address is http://vinho-brasil.blogspot.com. A hug.