Active Record

  Insert

 

        New model objects are created using a object = Class.new ... object.save paradigm.
        The following methods are supported:
 
        Explicit:
 
        object = class.new
        object.attribute = value
        ...
        object.save
 
        Block:
 
        Class.new do |obj|
              
            obj.attribute = value
            ...
            obj.save
 
        end
 
        Hash:
 
        obj = Class.new (
           
            :attribute => value
            ...
        )
        obj.save
 
        Note: the new constructor creates a new Class object in memory - but the save
        method must be called in order to save it to the database.
 
        .save returns true if successful, nil if not.
        .save! returns true if successful but raises an exception if not.
 
 
        Use of the AR create method will both instantiate the model object _and_ store
        it in the database. This method can only be used with a hash of attributes or
        an array of attribute hashes:
 
        obj = Class.create( :attribute => value, ... )
 
        objs = Class.create
        ([ 
               { :attribute => value, ... },
               ...
               { :attribute => value, ... }
       
        ])
 
        Note:
 
        .create returns an AR object regardless of successful saving. The returned object
        will need to be checked for validation errors in order to determine if data was
        saved or not.
 
        .create! returns an AR object if successful, but raises an exception if not.


  Update 

 

        Given an AR object, calling it's save method will either create a new record
        or update an existing one.
 
        AR will use the PK column (id) to match itself with a table row. The attributes
        in the AR object determine which columns will be updated, and such columns will
        only be updated if their value has changed.
 
        Hence in,
 
        ord = Order.find(12)
        ord.name = "Foo"
        ord.save
 
        All columns in the row for Order 12 can be updated (although only :name
        in this example).
 
        Whilst in,
 
        ords = Order.find_by_sql("select id, name, pay_type from orders where id = 12")
        first = ords[0]
        first.name = Bar"
        first.pay_type = "po"
        first.save
 
        only the :name and :pay_type columns will update in the associated row.
 
        Other update methods -
 
        (1) update_attribute(): update an attribute or a hash of attributes in a single call:
 
        ord = Order.find(12)
        ord.update_attribute(:name, "Foo")
 
        ord = Order.find(12)
        ord.update_attributes(:name => "Foo", pay_type => "po")
       
        (2) update/update_all:
       
        The update method takes an id parameter and a set of attributes. It fetches the
        corresponding row, updates the attributes, saves the result to the database, and
        returns the model object.
 
        Note: an array of ids and an array of attribute hashes may also be sent to this method
        resulting in the update of multiple rows, which are then returned.
 
        Update_all('set clause', 'where clause')  method allows one to specify the set
        and where clauses of the SQL update statement. What this method returns is
        adapter specific - but it is most commonly the number of rows changed.


  Delete

 
        Only 2 styles of delete are supported:
 
        (1) delete / delete_all (Class level)
 
        Explicit or Hash -
 
               delete(:id) or delete([:id])         
   
               A given condition (where clause) -
 
               Order.delete_all(["fillDate <= ?", @some_ancient_date])     
 
        (2) destroy / destroy_all (instance/class level)
 
	    instance level:

                ord = Order.find_by_name("Foo");
                ord.destroy
    
                This method deletes the row from the database which corresponds to the
                model object and then freezes the contents of that object, preventing further
                changes to the attributes.
 
	    class level:

                destroy takes an id or arrays of ids, destroy_all takes a condition (as with delete 
	    above).
 
        Both read the corresponding rows in the database tables into model objects and
        call the instance level destroy method of each object. Neither method returns 
	    anything meaningful.
 
        What is the difference between delete and destroy?
 
        The delete methods bypass the various AR callback and validation functions, while
        destroy methods ensure that they are all invoked.
 
        It is, in general, better to use the destroy methods if one wishes to ensure that
        ones database is consistent according to the business rules define in ones model
        classes.


Few things about Primary Keys and Ids

 
        Rails manages the creation of primary keys for new schemas: all tables have an id primary
        key column added to them. Note, that AR does provide a simple means of overriding this default
        by using the following construct:

        class LegacyBook < ActiveRecord::Base
	       self.primary_key = "your PK Name"
        end

        Warning: As far as AR is concerned, the PK attribute is always set using an attribute called id.
        The .primary_key = declaration sets the name of the column to use in the table. In the following code, we
        use an attribute id even though the PK in the DB is "your PK Name":

        book = LegacyBook.New
        book.id = "3225453453"
        book.title = "Blah"
        book.save

        book = LegacyBook.find("3225453453")
        puts book.title	# => "Blah"
        puts book.attributes #=> { "your PK Name" => "3225453453", "title" => "Blah" }

        Just to make things more confusing, the attributes of the model object have the names "your PK Name",
        "title" - id does not appear. When you need to set the PK, use id. At all other times
        use the actual column name.

        Note: Rails does NOT support composite PKs.