• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ruby on rails
 

Ruby on rails

on

  • 1,371 views

This presentation is used in Vinsol (Delhi) for educational purpose only.

This presentation is used in Vinsol (Delhi) for educational purpose only.

Statistics

Views

Total Views
1,371
Views on SlideShare
1,371
Embed Views
0

Actions

Likes
0
Downloads
12
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Ruby on rails Ruby on rails Presentation Transcript

      • Part-1
      • Migrations
      • Active Record
      • Part -2
      • Associations
      • Validations
      • Callbacks
      • Part -3
      • Testing
      Topics
    • Migrations
    • Migration allows you to define changes to your database schema What is migration?
    • Why Migration?
      • iteratively improving schema
      • keep things synchronized
    • The model and scaffold generators will create migrations appropriate for adding a new model. Auto generated migrations
    • ruby script/generate model Product name:string description:text my_app/db/migrate/001_create_products.rb Creating a model
    • Migration generated class CreateProducts < ActiveRecord::Migration def self.up create_table : products do |t| t.string :name t.text :description t.timestamps end end def self.down drop_table :products end end
    • self.up / self.down
    • ruby script/generate migration AddPartNumberToProducts part_number:string my_app/db/migrate/002_AddPartNumberToProducts.rb Creating a Standalone Migration
    • Migration generated class AddPartNumberToProducts < ActiveRecord::Migration def self.up add_column :products, :part_number, :string end def self.down remove_column :products, :part_number end end
    • rake db:migrate also invokes the db:schema:dump task
    • schema_migrations table
    • Other Transformations
    • def self.up create_table :people do |t| t.string :username, :null => false t.string :fname,lname t.text :notes t.timestamps end end def self.down drop_table :people end Creating a table
    • More transformations rename_column :people , :fname , :first_name rename_table old_name , new_name change_column table_name , column_name , type remove_column table_name , column_name add_index table_name , column_name drop_table table_name
    • More... change_table :products do |t| t. remove :description, :name t. string :part_number t. index :part_number t. rename :upccode, :upc_code end
    • Rollback rake db:rollback rake db:rollback STEP=3 rake db:migrate VERSION=20080906120000
    • ActiveRecord
    • ActiveRecord is a Module ActiveRecord (note no space) could be classed as a module, since it's an implementation of the Active Record design pattern. (* need to ask)
    • One Class Per Table
      • CREATE TABLE `people` (
      • `id` int(11) NOT NULL auto_increment,
      • `login` varchar(255),
      • `email` varchar(255),
      • `password` varchar(40),
      • `created_at` datetime default NULL,
      • `updated_at` datetime default NULL,
      • PRIMARY KEY (`id`)
      • ) ENGINE=InnoDB
    • One Object / instance Per Row
    • Table columns map to Object attributes
    • Some Key Points
      • mapping class names to table names .
      • pluralized table names.
      • integer primary keys.
      • classname _id as foreign keys .
    • Why Active Record
      • for simplicity and ease of use
      • hides low level implementation
    • The Basics
      • Select * from people where id='2' limit='1'
      • class Person < ActiveRecord::Base
      • end
      • person=Person.find(2)
    • find method Examples: User. find (23) User.find(:first) User.find(:all, :offset => 10, :limit => 10) User.find(:first).articles
    • Find :select list = Person.find(:all, :select => &quot;fname, lname&quot; )
    • Find with :conditions Student.find(:all, :conditions => [‘first_name = ? and status = ?’ ,‘mohit’, 1] ) Why this ?
    • Find: Order By Person.find(:all, :order => ‘updated_at DESC’ ) SQL: SELECT * FROM people ORDER BY created_at;
    • Find: Group By Person.find(:all, :group => ‘designation’ ) SQL: SELECT * FROM people GROUP BY designation;
    • Find: Limit & Offset Person.find(:all, :limit => 10, :offset => 0 ) SQL: SELECT * FROM people LIMIT 0, 10
    • Dynamic find methods person = Person.find_ by_fname (&quot;mohit&quot;) all_mohit = Person.find_ all_by_fname (&quot;mohit&quot;) person = Person.find_ by_fname_and_lname (&quot;mohit&quot;,”jain”)
    • Creating a new record user = User.new user.name = &quot;David&quot; user.occupation = &quot;Code Artist“ user .save OR user =User. new (:name => &quot;David&quot;, :occupation => &quot;Code Artist&quot;) user .save OR user =User .create (:name => &quot;David&quot;, :occupation => &quot;Code Artist&quot;)
    • Update a record person = Person.find(123) person .update_attribute(:name, &quot;Barney&quot; ) OR person= Person.find(123) person .name = &quot;mohit” person.save OR person=Person. update(12, :name => &quot;jigar&quot; , :email => &quot;jigar@vinsol.com&quot; ) update_all and update_attribute bypass the validations.
    • Delete a record Person. delete (123) OR person = Person.find_by_name(&quot;Mohit&quot;) person. destroy
    • Named and Anonymous Scopes
    • class Organization < ActiveRecord::Base has_many :people named_scope :active, :conditions => { :active => 'Yes' } end class Person < ActiveRecord::Base belongs_to :organization end Named scope
    • Usage Organization.active Organization.active.people
    • Named scope example 2 class Order < ActiveRecord::Base named_scope :last_n_days, lambda { |days| :condition => ['updated < ?' , days] } named_scope :checks, :conditions => {:pay_type => :check} end orders = Orders.last_n_days(7) orders = Orders.checks.last_n_days(7)
    • Anonymous scopes in_house = Orders.scoped(:conditions => 'email LIKE &quot;%@pragprog.com&quot;' ) in_house.checks.last_n_days(7)
    • Thank You.
    • Associations
      • belongs_to
      • has_one
      • has_many
      • has_many :through
      • has_one :through
      • has_and_belongs_to_many
      Types of associations
    • Whats the need ?
    • class Customer < ActiveRecord::Base end class Order < ActiveRecord::Base end OR class Customer < ActiveRecord::Base has_many :orders, :dependent => :destroy end class Order < ActiveRecord::Base belongs_to :customer end Comparison: without and with
    • The belongs_to Association
    • The has_one Association
    • One to One
    • The has_many Association
    • One to Many
    • Its: has_many : orders and has_one : order
    • has_many :through
    • has_and_belongs_to_many
    • has_and_belongs_to_many Stories can belong to many categories. Categories can have many stories. Categories_Stories Table story_id | category_id has_many through: -- gives you a third model Person can subscribe to many magazines. Magazines can have many subscribers. Subscriptions Table person_id | magazine_id | subscription_type | subscription_length | subscription_date has_and_belongs_to_many vs has_many :through
    • Many to many
    • has_one :through
    • has_one:through* class Magazine < ActiveRecord::Base has_many :subscriptions end class Subscription < ActiveRecord::Base belongs_to :magazine belongs_to :user end class User < ActiveRecord::Base has_many :subscriptions has_one :magazine, :through => : subscriptions, :conditions => ['subscriptions.active = ?', true] end
    • Polymorphic Associations
    • Self refrentional Joins class Employee < ActiveRecord::Base has_many :subordinates , :class_name => &quot;Employee&quot; , : foreign_key => &quot;manager_id&quot; belongs_to :manager , :class_name => &quot;Employee&quot; end
    • When Things Get Saved class Order < ActiveRecord::Base has_one :invoice end class Invoice < ActiveRecord::Base belongs_to :order end continue...
    • When things get saved (continue) If you assign an object to a has_one/has_many association in an existing object, that associated object will be automatically saved. order = Order.find(some_id) an_invoice = Invoice.new(...) order.invoice = an_invoice # invoice gets saved continue...
    • When things get saved (continue) If instead you assign a new object to a belongs_to association, it will never be automatically saved. order = Order.new(...) an_invoice.order = orde r # Order will not be saved here an_invoice.save # both the invoice and the order get saved
    • Validations
    • validates_acceptance_of validates_confirmation_of validates_length_of validates_numericality_of validates_presence_of Validation Helpers
    • Example of validator helper class Person < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name, :on => :create, :message => &quot;is already used&quot; end
    • When Does Validation Happen? new_record? instance method
    • Method triggers validations * create * create! * save * save! * update * update_attributes * update_attributes!
    • Method skips validations * update_all * update_attribute * update_counters * save(false)
    • valid? and invalid?
    • Validation Errors errors.add_to_base errors.add errors.clear errors.size
    • Displaying Validation Errors error_messages error_messages_for
    • Showing error message OR <%= error_messages_for :product %> <% form_for(@product) do |f| %> <%= f. error_messages %> #----- <% end %>
    • Callbacks
    • monitoring the process. The life cycle of a model object methods that get called at certain moments of an object’s lifecycle What are callbacks
    • Active Record defines 20 callbacks .
    • 18 call backs
    • after_initialize and after_find Rest two callbacks
    • 1.Instance method 2.Handlers Define callbacks:- in two ways
    • callback as instance method class class_name < ActiveRecord::Base # .. def before_save # .. end end
    • Callbacks as handlers
        class Order < ActiveRecord::Base before_save : normalize_credit_card protected def normalize_credit_card #...... end end
    • Observers
      • Same as callbacks
      • It's about separation of concerns.
      • factor out code that doesn't really belong in models
    • class OrderObserver < ActiveRecord::Observer observe Order end
    • Instantiating Observers config.active_record.observers= :order_observer ( in environment.rb )
    • Thank you
    • Testing
    • 1. Unit 2. Functional 3. Integration Testing type
    • Unit testing? What and why
    • rake db:test:prepare copy the schema
    • rake test:units 1.copies the schema 2. runs all the tests in the test/unit
    • require 'test_helper' class ProductTest < ActiveSupport::TestCase # Replace this with your real tests. test &quot; the truth &quot; do assert true end end Test file?
    • Running a test ruby -I test test/unit /product_test.rb
    • Understanding with example of Product model
    • validates_presence_of :title , :description , :image_url validates_numericality_of :price validate :price_must_be_at_least_a_cent validates_uniqueness_of :title validates_format_of :image_url, :with => %r{.(gif|jpg|png)$}i, :message => 'must be a URL for GIF, JPG ' + 'or PNG image.' protected def price_must_be_at_least_a_cent errors.add(:price, 'should be at least 0.01' ) if price.nil? || price < 0.01 end Product Model
    • test &quot; invalid with empty attributes &quot; do product = Product.new assert !product.valid? assert product.errors. invalid?(:title) assert product.errors. invalid?(:description) assert product.errors. invalid?(:price) assert product.errors. invalid?(:image_url) end Test 1
    • Run the test case ruby -I test test/unit/product_test.rb #Loaded suite test/unit/product_test #Started #.. #Finished in 0.092314 seconds. 2 tests, 6 assertions, 0 failures, 0 errors
    • Test 2 test &quot;positive price&quot; do product = Product.new(:title => &quot;My Book Title&quot; , :description => &quot;yyy&quot; , :image_url => &quot;zzz.jpg&quot; ) product.price = -1 assert !product.valid? assert_equal &quot;should be at least 0.01&quot; , product.errors.on(:price) product.price = 0 assert !product.valid? assert_equal &quot;should be at least 0.01&quot; , product.errors.on(:price) product.price = 1 assert product.valid? end
    • Fixtures sample data
    • ruby_book: title: Programming Ruby description: Dummy description price: 1234 image_url: ruby.png rails_book: title: Agile Web Development with Rails description: Dummy description price: 2345 image_url: rails.png YAML fixtures
    • Naming convention & usage fixtures :products Mention this in the ProductTest class :products => name of table and YML file
    • Fixture loading Loading involves three steps: * Remove any existing data * Load the fixture data * Dump the fixture data into a variable in case you want to access it directly
    • Test 3 (using fixture) test &quot;unique title1&quot; do product = Product.new(:title => products(:ruby_book).title , :description => &quot;yyy&quot; , :price => 1, :image_url => &quot;fred.gif&quot; ) assert !product.save
    • Assertions Available
                    • assert ( boolean , [msg] )
                    • assert_equal ( obj1 , obj2 , [msg] )
                    • assert_not_equal ( obj1 , obj2 , [msg] )
                    • assert_same ( obj1 , obj2 , [msg] )
                    • assert_instance_of ( class , obj , [msg] )
    • Thank you
    • WEB v2.0