<ul>Part-1 <li>Migrations
Active Record
Part -2
Associations
Validations
Callbacks
Part -3
Testing </li></ul>Topics
Migrations
Migration allows you to define  changes  to your  database schema What is migration?
Why Migration? <ul><li>iteratively  improving schema
keep things  synchronized </li></ul>
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.stri...
self.up / self.down
ruby script/generate migration  AddPartNumberToProducts   part_number:string my_app/db/migrate/002_AddPartNumberToProducts...
Migration generated class AddPartNumberToProducts < ActiveRecord::Migration   def  self.up   add_column :products, :part_n...
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.t...
More transformations rename_column   :people ,  :fname ,  :first_name rename_table   old_name ,  new_name change_column   ...
More... change_table   :products  do |t|  t. remove  :description,  :name  t. string  :part_number  t. index  :part_number...
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 Ac...
One Class Per Table <ul><li>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 </li></ul>
One Object / instance   Per   Row
Table columns   map to   Object attributes
Some Key Points <ul><li>mapping   class names  to  table names .
pluralized  table names.
integer  primary keys.
classname _id as  foreign keys . </li></ul>
Why Active Record <ul><li>for  simplicity  and ease of use
hides  low level implementation </li></ul>
The Basics <ul><li>Select * from people where id='2' limit='1' </li></ul><ul><li>class Person < ActiveRecord::Base
end
person=Person.find(2) </li></ul>
find method Examples:  User. find (23)  User.find(:first)  User.find(:all, :offset => 10, :limit => 10)  User.find(:first)...
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;mohi...
Creating a new record user = User.new user.name = &quot;David&quot; user.occupation = &quot;Code Artist“ user .save OR use...
Update a record person = Person.find(123)  person .update_attribute(:name, &quot;Barney&quot; ) OR person= Person.find(123...
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 c...
Usage Organization.active Organization.active.people
Named scope example 2 class  Order  < ActiveRecord::Base named_scope :last_n_days, lambda { |days| :condition => ['updated...
Anonymous scopes in_house = Orders.scoped(:conditions => 'email LIKE &quot;%@pragprog.com&quot;' ) in_house.checks.last_n_...
Thank You.
Associations
<ul><li>belongs_to
has_one
has_many
has_many :through
has_one :through
has_and_belongs_to_many </li></ul>Types of associations
Whats the  need ?
class  Customer  < ActiveRecord::Base  end  class  Order  < ActiveRecord::Base  end  OR class  Customer  < ActiveRecord::B...
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...
Many  to  many
has_one :through
has_one:through* class  Magazine  < ActiveRecord::Base has_many :subscriptions end class  Subscription  < ActiveRecord::Ba...
Polymorphic Associations
Self refrentional Joins class  Employee  < ActiveRecord::Base has_many :subordinates ,  :class_name => &quot;Employee&quot...
When Things Get Saved class  Order  < ActiveRecord::Base has_one :invoice end class  Invoice  < ActiveRecord::Base belongs...
When things get saved (continue) If you assign an object to a has_one/has_many association in an existing object, that ass...
When things get saved (continue) If instead you assign a new object to a belongs_to association, it will never be automati...
Validations
validates_acceptance_of validates_confirmation_of validates_length_of validates_numericality_of validates_presence_of Vali...
Example of validator helper class Person < ActiveRecord::Base  validates_presence_of   :name    validates_uniqueness_of  :...
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  %> ...
Callbacks
monitoring the process.   The life cycle of a model object methods that get called at  certain moments  of an object’s lif...
Active Record defines  20 callbacks .
18 call backs
after_initialize  and  after_find Rest two callbacks
Upcoming SlideShare
Loading in …5
×

Ruby on rails

1,307 views
1,206 views

Published on

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

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,307
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
24
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Ruby on rails

  1. 1. <ul>Part-1 <li>Migrations
  2. 2. Active Record
  3. 3. Part -2
  4. 4. Associations
  5. 5. Validations
  6. 6. Callbacks
  7. 7. Part -3
  8. 8. Testing </li></ul>Topics
  9. 9. Migrations
  10. 10. Migration allows you to define changes to your database schema What is migration?
  11. 11. Why Migration? <ul><li>iteratively improving schema
  12. 12. keep things synchronized </li></ul>
  13. 13. The model and scaffold generators will create migrations appropriate for adding a new model. Auto generated migrations
  14. 14. ruby script/generate model Product name:string description:text my_app/db/migrate/001_create_products.rb Creating a model
  15. 15. 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
  16. 16. self.up / self.down
  17. 17. ruby script/generate migration AddPartNumberToProducts part_number:string my_app/db/migrate/002_AddPartNumberToProducts.rb Creating a Standalone Migration
  18. 18. 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
  19. 19. rake db:migrate also invokes the db:schema:dump task
  20. 20. schema_migrations table
  21. 21. Other Transformations
  22. 22. 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
  23. 23. 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
  24. 24. More... change_table :products do |t| t. remove :description, :name t. string :part_number t. index :part_number t. rename :upccode, :upc_code end
  25. 25. Rollback rake db:rollback rake db:rollback STEP=3 rake db:migrate VERSION=20080906120000
  26. 26. ActiveRecord
  27. 27. 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)
  28. 28. One Class Per Table <ul><li>CREATE TABLE `people` (
  29. 29. `id` int(11) NOT NULL auto_increment,
  30. 30. `login` varchar(255),
  31. 31. `email` varchar(255),
  32. 32. `password` varchar(40),
  33. 33. `created_at` datetime default NULL,
  34. 34. `updated_at` datetime default NULL,
  35. 35. PRIMARY KEY (`id`)
  36. 36. ) ENGINE=InnoDB </li></ul>
  37. 37. One Object / instance Per Row
  38. 38. Table columns map to Object attributes
  39. 39. Some Key Points <ul><li>mapping class names to table names .
  40. 40. pluralized table names.
  41. 41. integer primary keys.
  42. 42. classname _id as foreign keys . </li></ul>
  43. 43. Why Active Record <ul><li>for simplicity and ease of use
  44. 44. hides low level implementation </li></ul>
  45. 45. The Basics <ul><li>Select * from people where id='2' limit='1' </li></ul><ul><li>class Person < ActiveRecord::Base
  46. 46. end
  47. 47. person=Person.find(2) </li></ul>
  48. 48. find method Examples: User. find (23) User.find(:first) User.find(:all, :offset => 10, :limit => 10) User.find(:first).articles
  49. 49. Find :select list = Person.find(:all, :select => &quot;fname, lname&quot; )
  50. 50. Find with :conditions Student.find(:all, :conditions => [‘first_name = ? and status = ?’ ,‘mohit’, 1] ) Why this ?
  51. 51. Find: Order By Person.find(:all, :order => ‘updated_at DESC’ ) SQL: SELECT * FROM people ORDER BY created_at;
  52. 52. Find: Group By Person.find(:all, :group => ‘designation’ ) SQL: SELECT * FROM people GROUP BY designation;
  53. 53. Find: Limit & Offset Person.find(:all, :limit => 10, :offset => 0 ) SQL: SELECT * FROM people LIMIT 0, 10
  54. 54. 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”)
  55. 55. 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;)
  56. 56. 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.
  57. 57. Delete a record Person. delete (123) OR person = Person.find_by_name(&quot;Mohit&quot;) person. destroy
  58. 58. Named and Anonymous Scopes
  59. 59. class Organization < ActiveRecord::Base has_many :people named_scope :active, :conditions => { :active => 'Yes' } end class Person < ActiveRecord::Base belongs_to :organization end Named scope
  60. 60. Usage Organization.active Organization.active.people
  61. 61. 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)
  62. 62. Anonymous scopes in_house = Orders.scoped(:conditions => 'email LIKE &quot;%@pragprog.com&quot;' ) in_house.checks.last_n_days(7)
  63. 63. Thank You.
  64. 64. Associations
  65. 65. <ul><li>belongs_to
  66. 66. has_one
  67. 67. has_many
  68. 68. has_many :through
  69. 69. has_one :through
  70. 70. has_and_belongs_to_many </li></ul>Types of associations
  71. 71. Whats the need ?
  72. 72. 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
  73. 73. The belongs_to Association
  74. 74. The has_one Association
  75. 75. One to One
  76. 76. The has_many Association
  77. 77. One to Many
  78. 78. Its: has_many : orders and has_one : order
  79. 79. has_many :through
  80. 80. has_and_belongs_to_many
  81. 81. 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
  82. 82. Many to many
  83. 83. has_one :through
  84. 84. 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
  85. 85. Polymorphic Associations
  86. 86. 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
  87. 87. When Things Get Saved class Order < ActiveRecord::Base has_one :invoice end class Invoice < ActiveRecord::Base belongs_to :order end continue...
  88. 88. 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...
  89. 89. 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
  90. 90. Validations
  91. 91. validates_acceptance_of validates_confirmation_of validates_length_of validates_numericality_of validates_presence_of Validation Helpers
  92. 92. 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
  93. 93. When Does Validation Happen? new_record? instance method
  94. 94. Method triggers validations * create * create! * save * save! * update * update_attributes * update_attributes!
  95. 95. Method skips validations * update_all * update_attribute * update_counters * save(false)
  96. 96. valid? and invalid?
  97. 97. Validation Errors errors.add_to_base errors.add errors.clear errors.size
  98. 98. Displaying Validation Errors error_messages error_messages_for
  99. 99. Showing error message OR <%= error_messages_for :product %> <% form_for(@product) do |f| %> <%= f. error_messages %> #----- <% end %>
  100. 100. Callbacks
  101. 101. 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
  102. 102. Active Record defines 20 callbacks .
  103. 103. 18 call backs
  104. 104. after_initialize and after_find Rest two callbacks
  105. 105. 1.Instance method 2.Handlers Define callbacks:- in two ways
  106. 106. callback as instance method class class_name < ActiveRecord::Base # .. def before_save # .. end end
  107. 107. Callbacks as handlers <ul>class Order < ActiveRecord::Base before_save : normalize_credit_card protected def normalize_credit_card #...... end end </ul>
  108. 108. Observers <ul><li>Same as callbacks </li></ul><ul><li>It's about separation of concerns.
  109. 109. factor out code that doesn't really belong in models </li></ul>
  110. 110. class OrderObserver < ActiveRecord::Observer observe Order end
  111. 111. Instantiating Observers config.active_record.observers= :order_observer ( in environment.rb )
  112. 112. Thank you
  113. 113. Testing
  114. 114. 1. Unit 2. Functional 3. Integration Testing type
  115. 115. Unit testing? What and why
  116. 116. rake db:test:prepare copy the schema
  117. 117. rake test:units 1.copies the schema 2. runs all the tests in the test/unit
  118. 118. 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?
  119. 119. Running a test ruby -I test test/unit /product_test.rb
  120. 120. Understanding with example of Product model
  121. 121. 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
  122. 122. 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
  123. 123. 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
  124. 124. 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
  125. 125. Fixtures sample data
  126. 126. 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
  127. 127. Naming convention & usage fixtures :products Mention this in the ProductTest class :products => name of table and YML file
  128. 128. 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
  129. 129. 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
  130. 130. Assertions Available <ul><ul><ul><ul><ul><ul><ul><ul><li>assert ( boolean , [msg] ) </li></ul></ul></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><ul><ul><li>assert_equal ( obj1 , obj2 , [msg] ) </li></ul></ul></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><ul><ul><li>assert_not_equal ( obj1 , obj2 , [msg] ) </li></ul></ul></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><ul><ul><li>assert_same ( obj1 , obj2 , [msg] ) </li></ul></ul></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><ul><ul><li>assert_instance_of ( class , obj , [msg] ) </li></ul></ul></ul></ul></ul></ul></ul></ul>
  131. 131. Thank you
  132. 132. WEB v2.0

×