w3d4 Flashcards

1
Q

What do ActiveRecord querying methods return?

A

An instance of ActiveRecord::Relation

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

When are Relation instances evaluated (i.e. a database query is fired)?

A

When they are directly accessed (i.e. via #each)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What happens to a Relation after a query is run?

A

After the query is run, the results are cached by Relation; they are stored for later re-use. Subsequent calls to each will not fire a query; they will instead use the prior result.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Say we want to re-fire a query after changing something in the db. What do we do?

A

Reload and ignore cached values by calling #query_method(true) on the instance in question.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What happens when we call ::where on a Relation?

A

A new Relation object is returned that reflects the query (note, however, that it is the existing relation that is queried, not the db. Furthermore, the already existing relation remains unchanged.)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What does #where_values do when called by a Relation?

A

It returns the results of the previous where query as a hash.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What happens when a method like #count is called on a Relation?

A

It forces the evaluation of a query, unlike most other query methods.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

How can we force the evaluation of a query?

A

With #load.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How do we prefetch an association, and why bother?

A

By using

self.table_name.includes(:association_name)

This allows us the fire off the query based on the defined association, and avoids overhead by needing to run the query later.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What does prefetching association allow us to do?

A

Use iterative (N+1) methods on the prefetched data without the normal SQL query overhead.

For example, if we do the following:

comments = user.comments.includes(:post, :parent_comment)

Then all of the following will work without hitting the db:

comments[0].post
comments[0].parent_comment
comments.each do |comment|

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How can we do a nested prefetch (for multi-level associations?)

A

posts = user.posts.includes(:comments => [:author, :parent_comment])

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What does ::joins require?

A

An association given as a symbol argument.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What does ::joins return, and how is this different from what ::includes returns?

A

joins does the opposite of includes:
# includes fetches the entries and the associated entries
both. User.joins(:comments) returns no Comment data, just
the User columns. For this reason, joins is used less
commonly than includes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What SQL operation does ::joins perform?

A

INNER JOIN

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

When should we use ::joins as opposed to ::includes?

A

When we want to do an aggregation (i.e. count), as opposed to a retrieval of all column values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

So, what is going on here?

posts_with_counts = self
.posts
.select(“posts., COUNT() AS comments_count”) # more in a sec
.joins(:comments)
.group(“posts.id”) # “comments.post_id” would be equivalent

A

We are creating an array of Post objects, but Rails is also able to dynamically add a new method to the returned Post objects, #comments_count, which stores the results of the SELECT clause which is also specified. Cool!

17
Q

What is going on here?

posts_with_counts = self
.posts
.select(“posts.*, COUNT(comments.id) AS comments_count”) # more in a sec
.joins(“LEFT OUTER JOIN comments ON posts.id = comments.post_id”)
.group(“posts.id”) # “comments.post_id” would be equivalent

A

We are performing a non-default LEFT OUTER JOIN to include posts with zero comments. Once again, Rails dynamically adds #comments_count to the returned Post objects.

18
Q

What is going on here?

start_time = (DateTime.now.midnight - 1.day)
end_time = DateTime.now.midnight
Comment.joins(:posts).where(
  'posts.created_at BETWEEN ? AND ?',
  start_time,
  end_time
).uniq
A

We are interpolating values into the where query to retrieve the unique posts from the previous day.

19
Q

What is a scope?

A

An ActiveRecord::Base class method which returns a relation.

20
Q

What is a dynamic finder and how do we use one?

A

Rails can figure out what to look for by making a method that builds on find_by

Application.find_by_email_address(“ned@appacademy.io”)

21
Q

How can we retrieve records in order?

A

Client.order(“orders_count ASC, created_at DESC”).all

22
Q

How can we use GROUP BY and HAVING clauses?

A

UserPost
.joins(:likes)
.group(“posts.id”)
.having(“COUNT(*) > 5”)

23
Q

How can we use our own SQL queries to access the db directly?

A

Use ::find_by_sql(«-SQL). This takes the standard heredoc format.

24
Q

When should we go into the db directly with ::find_by_sql ?

A

When our queries grow to a complexity that it becomes too much of a hassle to figure out in AR. AR is meant to ease your burden on easy queries, not add to it.

25
Q

How do we use ::find_by_sql with interpolated values?

A

Pass the arguments AND the query in an array:

Post.find_by_sql(
  [
    "SELECT title FROM posts WHERE author = ? AND created > ?",
    author_id,
    start_date
  ]
)
26
Q

What does ::find_by_sql return?

A

An array of objects.