Posted about 4 years ago. Visible to the public.

ActiveRecord scopes [4d]

Goals

  • Understand what scopes are and how they differ from arrays
  • Understand how a purely object-oriented approach of dealing with data doesn't scale.
  • Get into a habit of off-loading list-related calculations (filtering, mapping) to the database
  • Learn about the N+1 query problem and eager loading
  • Get into a habit of explicitly resolving scopes to arrays by calling to_a (don't let it happen by accident)
  • Understand the difference between "named scopes" and ad-hoc scopes using where
  • Understand how the scope creation syntax changed between Rails 2.3 and Rails 3+

Resources

Exercises

Search for MovieDB

In MovieDB, implement a method Movie.search(query) that returns a scope of movies matching the given query:

  • The query is a list of space-separated words that all need to appear in the movie title in order for the movie to match (e. g. event horizon)
  • A word can be prefixed by a minus character to exclude that word (e.g. event -horizon).
  • Make sure that the returned value is not an array but a scope that can be chained further. E.g. I should be able to use it like this:

    Copy
    Movie.search('event -main').search('horizon').where('year > 1995').order(:year).to_a
  • In the MovieDB UI, put a search box over the movies list that is backed by Movie.search.
  • Write both a Cucumber scenario and RSpec examples for the search functionality, using the guidelines from the "Testing" chapter in Growing Rails Applications in Practice.
    • RSpec examples should cover all edge cases
    • Cucumber scenario should only cover one "happy path" to show successful integration

Open budgets in Project Hero (makandra only)

In Project Hero (a Rails 2.3 project), build a view that lists all projects that have open (unclosed) budgets with unused amounts:

Copy
+----------------------------+-----------------------------------+ | Project | Unused amount in all open budgets | +----------------------------+-----------------------------------+ | Foo | 200 € | | Bar | 150.000 € | +----------------------------+-----------------------------------+
  • First, build it naively by iterating over all projects, iterating over the budgets of each project, etc.
  • Ask someone for a dump of the makandra stage and load it, tail -f log/development.log and observe the performance of your view. How many MySQL queries does it trigger? How many ActiveRecord objects are instantiated?
  • Now build a version of your view that does the same number of queries regardless of how many projects, budgets, activities, etc. you have. It should also not instantiate thousands of ActiveRecord objects, regardless of the database size.
  • When you're done: Can you move your code to a BudgetReport class with a nice API?
  • Note: Please don't use any existing classes that solve a similar problem in PH, such as BudgetCalculator or Analysis::Budgets.

Owner of this card:

Avatar
Henning Koch
Last edit:
19 days ago
by Hannes Randow
Keywords:
relations
Posted by Henning Koch to makandra Curriculum
This website uses cookies to improve usability and analyze traffic.
Accept or learn more