Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

ActiveRecord Query Interface (1), Season 1 Slide 1 ActiveRecord Query Interface (1), Season 1 Slide 2 ActiveRecord Query Interface (1), Season 1 Slide 3 ActiveRecord Query Interface (1), Season 1 Slide 4 ActiveRecord Query Interface (1), Season 1 Slide 5 ActiveRecord Query Interface (1), Season 1 Slide 6 ActiveRecord Query Interface (1), Season 1 Slide 7 ActiveRecord Query Interface (1), Season 1 Slide 8 ActiveRecord Query Interface (1), Season 1 Slide 9 ActiveRecord Query Interface (1), Season 1 Slide 10 ActiveRecord Query Interface (1), Season 1 Slide 11 ActiveRecord Query Interface (1), Season 1 Slide 12 ActiveRecord Query Interface (1), Season 1 Slide 13 ActiveRecord Query Interface (1), Season 1 Slide 14 ActiveRecord Query Interface (1), Season 1 Slide 15 ActiveRecord Query Interface (1), Season 1 Slide 16 ActiveRecord Query Interface (1), Season 1 Slide 17 ActiveRecord Query Interface (1), Season 1 Slide 18 ActiveRecord Query Interface (1), Season 1 Slide 19 ActiveRecord Query Interface (1), Season 1 Slide 20 ActiveRecord Query Interface (1), Season 1 Slide 21 ActiveRecord Query Interface (1), Season 1 Slide 22 ActiveRecord Query Interface (1), Season 1 Slide 23 ActiveRecord Query Interface (1), Season 1 Slide 24 ActiveRecord Query Interface (1), Season 1 Slide 25 ActiveRecord Query Interface (1), Season 1 Slide 26 ActiveRecord Query Interface (1), Season 1 Slide 27 ActiveRecord Query Interface (1), Season 1 Slide 28 ActiveRecord Query Interface (1), Season 1 Slide 29 ActiveRecord Query Interface (1), Season 1 Slide 30 ActiveRecord Query Interface (1), Season 1 Slide 31 ActiveRecord Query Interface (1), Season 1 Slide 32 ActiveRecord Query Interface (1), Season 1 Slide 33 ActiveRecord Query Interface (1), Season 1 Slide 34 ActiveRecord Query Interface (1), Season 1 Slide 35 ActiveRecord Query Interface (1), Season 1 Slide 36 ActiveRecord Query Interface (1), Season 1 Slide 37 ActiveRecord Query Interface (1), Season 1 Slide 38 ActiveRecord Query Interface (1), Season 1 Slide 39 ActiveRecord Query Interface (1), Season 1 Slide 40 ActiveRecord Query Interface (1), Season 1 Slide 41 ActiveRecord Query Interface (1), Season 1 Slide 42 ActiveRecord Query Interface (1), Season 1 Slide 43 ActiveRecord Query Interface (1), Season 1 Slide 44 ActiveRecord Query Interface (1), Season 1 Slide 45 ActiveRecord Query Interface (1), Season 1 Slide 46 ActiveRecord Query Interface (1), Season 1 Slide 47 ActiveRecord Query Interface (1), Season 1 Slide 48 ActiveRecord Query Interface (1), Season 1 Slide 49 ActiveRecord Query Interface (1), Season 1 Slide 50 ActiveRecord Query Interface (1), Season 1 Slide 51 ActiveRecord Query Interface (1), Season 1 Slide 52 ActiveRecord Query Interface (1), Season 1 Slide 53 ActiveRecord Query Interface (1), Season 1 Slide 54
Upcoming SlideShare
Make your app idea a reality with Ruby On Rails
Next
Download to read offline and view in fullscreen.

2 Likes

Share

Download to read offline

ActiveRecord Query Interface (1), Season 1

Download to read offline

제9차 ROR Lab 강의록입니다.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

ActiveRecord Query Interface (1), Season 1

  1. 1. The 9th Round of ROR Lab. Active Record Query Interface(1) March 17th, 2012 Hyoseong Choi ROR Lab.
  2. 2. ActiveRecord • No more SQL statements MySQL PostgreSQL : select * from tables SQLite ... ORM Active • SQL query Record • Fire Finder • Ruby object Methods • after_find callback ROR Lab.
  3. 3. Finder Methods of ActiveRecord 1.where 2.select 3.group 4.order 5.reorder 6.reverse_order 7.limit 8.offset 9.joins 10.includes 11.lock 12.readonly 13.from 14.having ActiveRecord::Relation ROR Lab.
  4. 4. Retrieving A Single Object • find • first • last • first! • last! ROR Lab.
  5. 5. Retrieving A Single Object - find - # Find the client with primary key (id) 10. client = Client.find(10) # => #<Client id: 10, first_name: "Ryan"> SELECT * FROM clients WHERE (clients.id = 10) ActiveRecord::RecordNotFound exception ROR Lab.
  6. 6. Retrieving A Single Object - first - client = Client.first # => #<Client id: 1, first_name: "Lifo"> SELECT * FROM clients LIMIT 1 nil if no matching record is found ROR Lab.
  7. 7. Retrieving A Single Object - last - client = Client.last # => #<Client id: 221, first_name: "Russel"> SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 nil if no matching record is found ROR Lab.
  8. 8. Retrieving A Single Object - first! - client = Client.first! # => #<Client id: 1, first_name: "Lifo"> SELECT * FROM clients LIMIT 1 RecordNotFound if no matching record ROR Lab.
  9. 9. Retrieving A Single Object - last! - client = Client.last! # => #<Client id: 221, first_name: "Russel"> SELECT * FROM clients ORDER BY clients.id DESC LIMIT 1 RecordNotFound if no matching record ROR Lab.
  10. 10. Retrieving Multiple Objects • Using multiple primary keys • In batches • find_each :batch_size, :start, • find_in_batches :batch_size, :start + find options (except for :order, :limit) ROR Lab.
  11. 11. Retrieving Multiple Objects - Using multiple primary keys - # Find the clients with primary keys 1 and 10. client = Client.find([1, 10]) # Or even Client.find(1, 10) # => [#<Client id: 1, first_name: "Lifo">, #<Client id: 10, first_name: "Ryan">] SELECT * FROM clients WHERE (clients.id IN (1,10)) ActiveRecord::RecordNotFound exception ROR Lab.
  12. 12. Retrieving Multiple Objects - in Batches - to iterate over a large set of records • find_each : each record to the block individually as a model • find_in_batches : the entire batch to the block as an array of models # This is very inefficient when the users table has thousands of rows. User.all.each do |user|   NewsLetter.weekly_deliver(user) end OK to 1,000 ROR Lab.
  13. 13. Retrieving Multiple Objects - in Batches : find_each - User.find_each do |user|   NewsLetter.weekly_deliver(user) end User.find_each(:batch_size => 5000) do |user|   NewsLetter.weekly_deliver(user) end User.find_each(:start => 2000, :batch_size => 5000) do |user|   NewsLetter.weekly_deliver(user) end ROR Lab.
  14. 14. Retrieving Multiple Objects - in Batches : find_each - Article.find_each { |a| ... } # => iterate over all articles, in chunks of 1000 (the default) Article.find_each(:conditions => { :published => true }, :batch_size => 100 ) { |a| ... } # iterate over published articles in chunks of 100 http://archives.ryandaigle.com/articles/ 2009/2/23/what-s-new-in-edge-rails-batched-find ROR Lab.
  15. 15. Retrieving Multiple Objects - in Batches : find_in_batches - # Give add_invoices an array of 1000 invoices at a time Invoice.find_in_batches(:include => :invoice_lines) do |invoices|   export.add_invoices(invoices) end options : • :batch_size & :start • options of find method (except :order and :limit) ROR Lab.
  16. 16. Retrieving Multiple Objects - in Batches : find_in_batches - Article.find_in_batches { |articles| articles.each { | a| ... } } # => articles is array of size 1000 Article.find_in_batches(:batch_size => 100 ) { |articles| articles.each { |a| ... } } # iterate over all articles in chunks of 100 class Article < ActiveRecord::Base scope :published, :conditions => { :published => true } end Article.published.find_in_batches(:batch_size => 100 ) { |articles| ... } # iterate over published articles in chunks of 100 ROR Lab.
  17. 17. Conditions - where - • String conditions • Array conditions • Hash conditions ROR Lab.
  18. 18. String Conditions Client.where("orders_count = ‘2’") ROR Lab.
  19. 19. Array Conditions Client.where("orders_count = ?", params[:orders]) Client.where("orders_count = ? AND locked = ?", params[:orders], false) X Client.where("orders_count = #{params[:orders]}") hacking!!! by SQL injection http://guides.rubyonrails.org/security.html#sql-injection ROR Lab.
  20. 20. Array Conditions - Placeholder conditions - Client.where("created_at >= :start_date AND created_at <= :end_date", {:start_date => params[:start_date], :end_date => params[:end_date]}) ROR Lab.
  21. 21. Array Conditions - Range conditions - Client.where(:created_at => (params[:start_date].to_date).. (params[:end_date].to_date)) SELECT "clients".* FROM "clients" WHERE ("clients"."created_at" BETWEEN '2010-09-29' AND '2010-11-30') ROR Lab.
  22. 22. Hash Conditions - Equality conditions - Client.where(:locked => true) Client.where('locked' => true) ROR Lab.
  23. 23. Hash Conditions - Range conditions - Client.where(:created_at => (Time.now.midnight - 1.day)..Time.now.midnight) SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00') ROR Lab.
  24. 24. Hash Conditions - Subset conditions - Client.where(:orders_count => [1,3,5]) SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5)) ROR Lab.
  25. 25. Ordering Client.order("created_at") Client.order("created_at DESC") # OR Client.order("created_at ASC") Client.order("orders_count ASC, created_at DESC") ROR Lab.
  26. 26. Selecting If the select method is used, all the returning objects will be read only. Client.select("viewable_by, locked") SELECT viewable_by, locked FROM clients ActiveModel::MissingAttributeError: missing attribute: <attribute> Client.select(:name).uniq SELECT DISTINCT name FROM clients query = Client.select(:name).uniq # => Returns unique names query.uniq(false) # => Returns all names, even if there are duplicates ROR Lab.
  27. 27. Limit & Offset Client.limit(5) SELECT * FROM clients LIMIT 5 Client.limit(5).offset(30) SELECT * FROM clients LIMIT 5 OFFSET 30 ROR Lab.
  28. 28. Group Order.select( "date(created_at) as ordered_date, sum(price) as total_price") .group("date(created_at)") SQL SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) ROR Lab.
  29. 29. Having Order.select( "date(created_at) as ordered_date, sum(price) as total_price") .group("date(created_at)") .having("sum(price) > ?", 100) SQL SELECT date(created_at) as ordered_date, sum(price) as total_price FROM orders GROUP BY date(created_at) HAVING sum(price) > 100 ROR Lab.
  30. 30. Overriding Conditions • except • only • reorder • reverse_order ROR Lab.
  31. 31. Overriding Conditions - except - Post.where('id > 10').limit(20).order('id asc').except(:order) SELECT * FROM posts WHERE id > 10 LIMIT 20 ROR Lab.
  32. 32. Overriding Conditions - only - Post.where('id > 10').limit(20).order('id desc').only(:order, :where) SELECT * FROM posts WHERE id > 10 ORDER BY id DESC ROR Lab.
  33. 33. Overriding Conditions - reorder - class Post < ActiveRecord::Base   ..   ..   has_many :comments, :order => 'posted_at DESC' end   Post.find(10).comments.reorder('name') SELECT * FROM posts WHERE id = 10 ORDER BY name SELECT * FROM posts WHERE id = 10 ORDER BY posted_at DESC ROR Lab.
  34. 34. Overriding Conditions - reverse_order - Client.where("orders_count > 10").order(:name).reverse_order SELECT * FROM clients WHERE orders_count > 10 ORDER BY name DESC Client.where("orders_count > 10").reverse_order SELECT * FROM clients WHERE orders_count > 10 ORDER BY clients.id DESC ROR Lab.
  35. 35. Readonly Objects client = Client.readonly.first client.visits += 1 client.save ActiveRecord::ReadOnlyRecord exception ROR Lab.
  36. 36. Locking Records for Update • To prevent “race conditions” • To ensure “atomic updates” • Two locking mechanisms ‣ Optimistic Locking : version control ‣ Pessimistic Locking : DB lock ROR Lab.
  37. 37. Optimistic Locking • “lock_version” in DB table (default to 0) • set_locking_column to change column name c1 = Client.find(1) c2 = Client.find(1)   c1.first_name = "Michael" c1.save # increments the lock_version column   c2.name = "should fail" c2.save # Raises an ActiveRecord::StaleObjectError ROR Lab.
  38. 38. Optimistic Locking • To turn off, ActiveRecord::Base.lock_optimistically = false • To override the name of the lock_version column class Client < ActiveRecord::Base   set_locking_column :lock_client_column end ROR Lab.
  39. 39. Pessimistic Locking • A locking mechanism by DB • An exclusive lock on the selected rows • Usually wrapped inside a transaction • Two types of Lock ‣ FOR UPDATE (default, an exclusive lock) ‣ LOCK IN SHARE MODE ROR Lab.
  40. 40. Pessimistic Locking Item.transaction do   i = Item.lock.first   i.name = 'Jones'   i.save end SQL (0.2ms)   BEGIN Item Load (0.3ms)   SELECT * FROM `items` LIMIT 1 FOR UPDATE Item Update (0.4ms)   UPDATE `items` SET `updated_at` = '2009-02-07 18:05:56', `name` = 'Jones' WHERE `id` = 1 SQL (0.8ms)   COMMIT ROR Lab.
  41. 41. Pessimistic Locking Item.transaction do   i = Item.lock("LOCK IN SHARE MODE").find(1)   i.increment!(:views) end item = Item.first item.with_lock do   # This block is called within a transaction,   # item is already locked.   item.increment!(:views) end ROR Lab.
  42. 42. Joining Tables - Using a String SQL Fragment - Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id') SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id ROR Lab.
  43. 43. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN • a Single Association • Multiple Associations • Nested Associations(Single Level) • Nested Associations(Multiple Level) ROR Lab.
  44. 44. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • a Single Association   belongs_to :category   has_many :comments   has_many :tags end Category.joins(:posts)   class Comment < ActiveRecord::Base   belongs_to :post   has_one :guest end SELECT categories.*   FROM categories class Guest < ActiveRecord::Base   INNER JOIN posts   belongs_to :comment end ON posts.category_id = categories.id   class Tag < ActiveRecord::Base   belongs_to :post “return a Category object for all categories with posts” end ROR Lab.
  45. 45. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • Multiple Associations   belongs_to :category   has_many :comments   has_many :tags end Post.joins(:category, :comments)   class Comment < ActiveRecord::Base   belongs_to :post   has_one :guest SELECT posts.* FROM posts end     INNER JOIN categories class Guest < ActiveRecord::Base ON posts.category_id = categories.id   belongs_to :comment   INNER JOIN comments end ON comments.post_id = posts.id   class Tag < ActiveRecord::Base “return all posts that have a category and at least one comment”   belongs_to :post end ROR Lab.
  46. 46. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • Nested Associations(Single Level)   belongs_to :category   has_many :comments   has_many :tags end Post.joins(:comments => :guest)   class Comment < ActiveRecord::Base   belongs_to :post   has_one :guest SELECT posts.* FROM posts end     INNER JOIN comments class Guest < ActiveRecord::Base ON comments.post_id = posts.id   belongs_to :comment   INNER JOIN guests end ON guests.comment_id = comments.id   class Tag < ActiveRecord::Base   belongs_to :post “return all posts that have a comment made by a guest” end ROR Lab.
  47. 47. Joining Tables - Using Array/Hash of Named Associations - only with INNER JOIN class Category < ActiveRecord::Base   has_many :posts end   class Post < ActiveRecord::Base • Nested Associations(Multiple Level)   belongs_to :category   has_many :comments   has_many :tags end Category.joins(:posts =>   class Comment < ActiveRecord::Base [{:comments => :guest}, :tags]   belongs_to :post   has_one :guest end   SELECT categories.* FROM categories class Guest < ActiveRecord::Base   INNER JOIN posts ON posts.category_id = categories.id   belongs_to :comment INNER JOIN comments ON comments.post_id = posts.id end   INNER JOIN guests ON guests.id = comments.quest_id class Tag < ActiveRecord::Base INNER JOIN tags ON tags.post_id = posts.id   belongs_to :post end ROR Lab.
  48. 48. Joining Tables - Specifying Conditions on the Joined Tables - : using Array and String Conditions time_range = (Time.now.midnight - 1.day)..Time.now.midnight Client.joins(:orders) .where('orders.created_at' => time_range) : using nested Hash Conditions time_range = (Time.now.midnight - 1.day)..Time.now.midnight Client.joins(:orders) .where(:orders => {:created_at => time_range}) ROR Lab.
  49. 49. Joining Tables - Inner Join - SELECT <select_list> FROM TableA A INNER JOIN TableB B ON A.Key = B.Key ROR Lab.
  50. 50. Joining Tables - Left Join - SELECT <select_list> SELECT <select_list> FROM TableA A FROM TableA A LEFT JOIN TableB B LEFT JOIN TableB B ON A.Key = B.Key ON A.Key = B.Key WHERE B.Key IS NULL ROR Lab.
  51. 51. Joining Tables - Right Join - SELECT <select_list> SELECT <select_list> FROM TableA A FROM TableA A RIGHT JOIN TableB B RIGHT JOIN TableB B ON A.Key = B.Key ON A.Key = B.Key WHERE A.Key IS NULL ROR Lab.
  52. 52. Joining Tables - Full Outer Join - SELECT <select_list> SELECT <select_list> FROM TableA A FROM TableA A FULL OUTER JOIN TableB B FULL OUTER JOIN TableB B ON A.Key = B.Key ON A.Key = B.Key WHERE A.Key IS NULL OR B.Key IS NULL ROR Lab.
  53. 53. ROR Lab.
  54. 54. 감사합니다.
  • itclock

    Feb. 20, 2015
  • AnijaSaraThomas

    Feb. 18, 2014

제9차 ROR Lab 강의록입니다.

Views

Total views

3,009

On Slideshare

0

From embeds

0

Number of embeds

1,284

Actions

Downloads

24

Shares

0

Comments

0

Likes

2

×