Skip to content

Commit e4ef204

Browse files
author
Elle Meredith
committed
Update day 2 slides with AR queries examples
1 parent b6baf3c commit e4ef204

1 file changed

Lines changed: 126 additions & 9 deletions

File tree

02-00-Day-2-session-slides.md

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ slide-transition: fade(0.4)
1616
- REST and routes
1717
- Addressing callbacks
1818
- What should go in ActiveRecord Models
19-
- Active support
20-
- Do we remember what SOLID is?
19+
- ActiveSupport
20+
2121

2222
---
2323
# Set up our app
@@ -26,7 +26,7 @@ App: [https://github.com/elle/survey_app](https://github.com/elle/survey_app)
2626

2727
1. Clone app
2828
2. `cd survey_app`
29-
3. Open `.ruby-version` and update with your Ruby version number
29+
3. Open `.ruby-version` and update with your Ruby version number. Also change Ruby version number in `Gemfile`
3030
4. `bundle exec rails db:create`
3131
5. `./bin/setup`
3232

@@ -134,6 +134,15 @@ Feel free to code along...
134134
---
135135
# ActiveRecord
136136

137+
---
138+
139+
[ActiveRecord docs](https://guides.rubyonrails.org/active_record_basics.html):
140+
141+
> Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose **data requires persistent storage to a database**.
142+
143+
---
144+
# ActiveRecord
145+
137146
When we create a new model
138147

139148
- Model is singular
@@ -149,7 +158,7 @@ When we create a new model
149158
---
150159
# Migrations
151160

152-
Reference: [Docs](https://guides.rubyonrails.org/v3.2/migrations.html)
161+
[Docs](https://guides.rubyonrails.org/v3.2/migrations.html)
153162

154163
## Transformations
155164

@@ -199,7 +208,7 @@ db/schema.rb or db/structure.sql
199208
---
200209
# Associations
201210

202-
In Rails, an association is a connection between two Active Record models.
211+
In Rails, an association is a connection between two ActiveRecord models.
203212

204213
```ruby
205214
class Person < ApplicationRecord
@@ -232,8 +241,118 @@ end
232241

233242
```ruby
234243
Person.where(first_name: "Natasha")
244+
Person.all
245+
Company.find(1).surveys.active.limit(5)
246+
Post.alphabetical
247+
248+
class Post < ApplicationRecord
249+
def self.alphabetical
250+
order(title: :asc)
251+
end
252+
end
253+
```
254+
255+
---
256+
# Domain models
257+
258+
```ruby
259+
class Person < ActiveRecord::Base
260+
belongs_to :role
261+
end
262+
263+
class Role < ActiveRecord::Base
264+
has_many :people
265+
end
266+
```
267+
268+
---
269+
# Question
270+
271+
We need to find all the people who belong to a billable role.
272+
273+
Can you think of ways to achieve this?
274+
275+
276+
---
277+
278+
```ruby
279+
# This works, but is not optimal
280+
Person.all.select { |person| person.role.billable? }
281+
```
282+
283+
---
284+
# Gluing tables together with the :joins method
285+
286+
```ruby
287+
Person.all.joins(:role)
288+
```
289+
290+
```sql
291+
SELECT "people".*
292+
FROM "people"
293+
INNER JOIN "roles"
294+
ON "roles.id" = "people"."role_id";
235295
```
236296

297+
---
298+
```ruby
299+
Person.all.joins(:role).where(roles: { billable: true })
300+
```
301+
302+
which generates SQL like this:
303+
304+
```sql
305+
SELECT "people".*
306+
FROM "people"
307+
INNER JOIN "roles"
308+
ON "roles.id" = "people"."role_id"
309+
WHERE "roles"."billable" = 't';
310+
```
311+
312+
And this query hits the database once!
313+
314+
---
315+
# Separating concerns with the merge method
316+
317+
Does billable logic fit on `Person` or `Role`?
318+
319+
---
320+
321+
```ruby
322+
class Role < ApplicationRecord
323+
def self.billable
324+
where(billable: true)
325+
end
326+
end
327+
```
328+
329+
And now, when we're querying people, we can use ActiveRecord's `merge` method to leverage this relation:
330+
331+
```ruby
332+
Person.joins(:role).merge(Role.billable)
333+
```
334+
335+
---
336+
# Complete solution
337+
338+
```ruby
339+
class Role < ApplicationRecord
340+
def self.billable
341+
where(billable: true)
342+
end
343+
end
344+
345+
class Person < ApplicationRecord
346+
def self.billable
347+
joins(:role).merge(Role.billable)
348+
end
349+
end
350+
351+
# And now we can just call
352+
Person.billable
353+
```
354+
355+
237356
---
238357
# Polymorphic associations
239358

@@ -431,7 +550,7 @@ A better approach is creating PORO service object.
431550
---
432551
# Activity
433552

434-
Add a `slug` attribute to the Survey object.
553+
Add a `slug` attribute to the `Survey` object.
435554

436555
Requirements:
437556

@@ -511,13 +630,11 @@ require "active_support/core_ext/string"
511630

512631
Check `02-11-active-support-core-extensions.rb`
513632

514-
---
515-
# Do we remember what SOLID is about?
516633

517634
---
518635
# Daily reflection ritual
519636

520-
[https://tally.so/forms/w8aEBY/edit](https://tally.so/forms/w8aEBY/edit)
637+
[https://tally.so/r/w8aEBY](https://tally.so/r/w8aEBY)
521638

522639
---
523640
# Daily feedback

0 commit comments

Comments
 (0)