Pages

Sunday, June 03, 2012

Difference between association constructor methods in ActiveRecord objects

Like any ORM, Active Records supports association constructor methods. Perhaps you would have known of this by a different term.

An example

     Anyway, consider a setup of a Post object that has belongs to a given user object. In the User model, the relation between a User and a Post is connected with a has_many relationship.

class User < ActiveRecord::Base
    ...
    has_many :posts, :dependent => :destroy # we declare          dependency because when we delete a user, we want all of his/her posts to be gone as well 
   ...
end


class Parts < ActiveRecord::Base
  ... 
  belongs_to :user 
  ...
 end

Association relations in (nested) objects

To access an association, we use the declared association symbol.
In the case of the example above, if we would like to access all posts related to a given user, we use the 'posts' symbol in the user object in question.

In the case where we have a new post to add, we could do either one below (assuming the user object pre-exist):
1) instantiate a new Post object with the parameter values from the input web form, assign the user object's identifier into the foreign key in the Post object
2) in the user object, access the Posts and send a message to the available association constructor methods. We then call either one of the available association constructor methods (see section below)

Available association constructor methods

Based on active records api for create_association and build_association, both association constructor methods will connect both the object and its nested object by defining the identifier of the object in the nested object's foreign key attribute
  1. create
    • this creates the object from the main object and saves the new object (provided that it passes its defined validations)
    • using this method means that a transaction is not required as the nested object would have already been saved if it's valid or would have thrown an exception if it was not valid
    • in the example here, the call will look like user.posts.create  
  2. build
    • this creates the object from the main object and does not save the new object
    • using this method means that a transaction is best used to ensure that should the new object fail in terms of validation, the database operations can be rolled back
    • in the example here, the call will look like user.posts.build