際際滷

際際滷Share a Scribd company logo
Querying with Rails
By Parth Modi
Index
 ORM - What, Why
 About ActiveRecord
 Migrations
 Models
 Relationships
 Queries
 Scopes
 What I learned so far
Object Relational Mapping
Connects the rich objects of an application to tables in a relational database
management system.
 No need to depend on Database
 No need to write SQL statements directly (Most of the time)
 Database Connection - Implementation Abstracted
 Lets you focus on Application
Active Record
Objects carry both persistent data and behavior which operates on that data. Active
Record takes the opinion that ensuring data access logic as part of the object will
educate users of that object on how to write to and read from the database.
 Associations
 Validations
 Different Database Operations in Object Oriented fashion
 Inheritance Hierarchies
Active Record
Migrations
 DDL commands
 Track changes in table schema, with time
 Never delete a migration script
 Know when to use rails db:migrate and when to rails db:schema:load
Models
 ActiveRecord backed
 Model lets you create objects that represents row of the table in database
 Attributes, Associations, Validations, Callbacks
 Conventions over Configuration
 http://guides.rubyonrails.org/active_record_basics.html
Associations
State
District District District
Pincode Pincode Pincode
What a rails model looks like
Queries
 #find, #find_by
 #select
 #where, #rewhere
 #order
 #group, #having
 #join, #left_outer_join
Queries - tends to get complex over time
 Get pincodes:
 SELECT pincodes.* FROM pincodes;
 Sort Pin Codes by code:
 SELECT pincodes.* FROM pincodes ORDER BY "pincodes"."code" ASC;
 Apply search:
 SELECT "pincodes".*
FROM "pincodes"
WHERE (code ILIKE '%SEARCH-TERM%')
ORDER BY "pincodes"."code" DESC
LIMIT 10
OFFSET 0;
 ActiveRecord sums all of this into:
Queries - and even before your app hits
production Get Pincodes from A certain State:
SELECT "pincodes".*
FROM "pincodes"
INNER JOIN "districts" ON "districts"."id" = "pincodes"."district_id"
INNER JOIN "states" ON "states"."id" = "districts"."state_id"
WHERE (code ILIKE '%SEARCH-TERM%') AND (states.name = 'Gujarat')
ORDER BY "pincodes"."code" DESC
LIMIT 10
OFFSET 0;
Queries - Readable? Concise?
 ActiveRecord equivalent of previous query:
Pincode.joins(district: [:state])
.where(states.name = ? , Gujarat)
.where('code ILIKE ?', '%SEARCH-TERM%')
.order(code: :desc)
.limit(10)
.offset(0)
 This goes on and on...
Queries - pagination, search, ordering, what not!
Scopes to the rescue
 Lambda Functions, with names ( ? )
 Always returns ActiveRecord::Relation object
 You can pass arguments as you would with normal methods
 Holds chunks of query logic
 Chainable
 http://guides.rubyonrails.org/active_record_querying.html#scopes
 https://www.justinweiss.com/articles/should-you-use-scopes-or-class-methods/
Pincode model After Applying scopes
Querying - with Scopes!
 And the query in becomes:
 Pincode.by_state('Gujarat').order_by('code').search('x').limit(10).offset(10)
Tips
 Fetch only data you need
 Ruby Methods vs Query Methods
 Use IN query
 Wrap batch processing inside transaction
 Never use #all, use #find_each
 Use #joins, #includes and #preload frequently
 https://www.sitepoint.com/n-1-when-more-queries-is-a-good-thing/
 https://blog.codeship.com/writing-efficient-queries/
Gracias!
Follow my articles at: parthrmodi.com/blog and github at github.com/8parth

More Related Content

Querying with Rails

  • 2. Index ORM - What, Why About ActiveRecord Migrations Models Relationships Queries Scopes What I learned so far
  • 3. Object Relational Mapping Connects the rich objects of an application to tables in a relational database management system. No need to depend on Database No need to write SQL statements directly (Most of the time) Database Connection - Implementation Abstracted Lets you focus on Application
  • 4. Active Record Objects carry both persistent data and behavior which operates on that data. Active Record takes the opinion that ensuring data access logic as part of the object will educate users of that object on how to write to and read from the database. Associations Validations Different Database Operations in Object Oriented fashion Inheritance Hierarchies
  • 6. Migrations DDL commands Track changes in table schema, with time Never delete a migration script Know when to use rails db:migrate and when to rails db:schema:load
  • 7. Models ActiveRecord backed Model lets you create objects that represents row of the table in database Attributes, Associations, Validations, Callbacks Conventions over Configuration http://guides.rubyonrails.org/active_record_basics.html
  • 9. What a rails model looks like
  • 10. Queries #find, #find_by #select #where, #rewhere #order #group, #having #join, #left_outer_join
  • 11. Queries - tends to get complex over time Get pincodes: SELECT pincodes.* FROM pincodes; Sort Pin Codes by code: SELECT pincodes.* FROM pincodes ORDER BY "pincodes"."code" ASC; Apply search: SELECT "pincodes".* FROM "pincodes" WHERE (code ILIKE '%SEARCH-TERM%') ORDER BY "pincodes"."code" DESC LIMIT 10 OFFSET 0; ActiveRecord sums all of this into:
  • 12. Queries - and even before your app hits production Get Pincodes from A certain State: SELECT "pincodes".* FROM "pincodes" INNER JOIN "districts" ON "districts"."id" = "pincodes"."district_id" INNER JOIN "states" ON "states"."id" = "districts"."state_id" WHERE (code ILIKE '%SEARCH-TERM%') AND (states.name = 'Gujarat') ORDER BY "pincodes"."code" DESC LIMIT 10 OFFSET 0;
  • 13. Queries - Readable? Concise? ActiveRecord equivalent of previous query: Pincode.joins(district: [:state]) .where(states.name = ? , Gujarat) .where('code ILIKE ?', '%SEARCH-TERM%') .order(code: :desc) .limit(10) .offset(0)
  • 14. This goes on and on... Queries - pagination, search, ordering, what not!
  • 15. Scopes to the rescue Lambda Functions, with names ( ? ) Always returns ActiveRecord::Relation object You can pass arguments as you would with normal methods Holds chunks of query logic Chainable http://guides.rubyonrails.org/active_record_querying.html#scopes https://www.justinweiss.com/articles/should-you-use-scopes-or-class-methods/
  • 16. Pincode model After Applying scopes
  • 17. Querying - with Scopes! And the query in becomes: Pincode.by_state('Gujarat').order_by('code').search('x').limit(10).offset(10)
  • 18. Tips Fetch only data you need Ruby Methods vs Query Methods Use IN query Wrap batch processing inside transaction Never use #all, use #find_each Use #joins, #includes and #preload frequently https://www.sitepoint.com/n-1-when-more-queries-is-a-good-thing/ https://blog.codeship.com/writing-efficient-queries/
  • 19. Gracias! Follow my articles at: parthrmodi.com/blog and github at github.com/8parth