This document discusses querying data with Rails, including using ActiveRecord and scopes. It introduces Object Relational Mapping (ORM) with ActiveRecord, how it allows interacting with databases in an object-oriented way using models. Migrations are used to track database schema changes. Relationships between models allow querying across associated data. Scopes help define reusable chunks of query logic to chain together. The document provides examples of building complex queries with ActiveRecord and shows how scopes can simplify them. Tips are given on optimizing queries for efficiency.
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
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;
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/
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/