305 Internal APIs and client-side rendering

In a web application you often need to move data between the client (HTML, Javascript) and the server (Ruby, Rails).

Step 1: Moving HTML snippets

Add a find-as-you-type search to MovieDB. Above the list of movies there should be a text input that updates the list with the search results as the user is typing in the query. The user should not have to press a "Search" button (hint: you can bind to the [input](https://makandracards.com/makandra/33699-input-a-dom-event-that-is-fired-whenever-a-text-field-cha...

315 Advanced Ruby: Metaprogramming and DSLs [3d]

Rubymonk training

Read the following Rubymonk articles:

316 Advanced Ruby: More metaprogramming with Modularity and ActiveSupport::Concern [2d]


Method lookup

Understand all the terms in How Ruby method lookup works, in particular:

  • include
  • extend
  • singleton class
  • prepend

Do you understand why object.extend(SomeModule) is the same as object.singleton_class.include(SomeModule)?

How does include and extend work together with inheritance?

You may also read more about the Ruby Object Model, if all o...

320 State machines [3d]


Movies in MovieDB should have one of the following workflow states:

  • draft
  • pending
  • published
  • declined

A movie always begins as a draft and then transitions through the states as it's getting reviewed. This could be a typical state flow for a movie:

    [*] --> draft
    draft --> pending
    pending --> declined: Reason
    declined --> pending
    pending --> published

Change the visibility rules (Consul powers) so:

  • All users can see published movies of other ...

325 Consuming external APIs with JavaScript [2d]

Exercise 1: Google Maps

  • In MovieDB, add a new field “Principal filming location”.
  • In a movie’s show view, geocode that location and show a Google map centered around it
  • Now write an E2E feature that tests that the map shows the correct location.


  • The purpose of this lesson to learn interacting with external APIs from JavaScript. Even though this exercise can be implemented trivially by embedding a Google Maps iframe, don't do that for the purpose of l...

326 Consuming external APIs with Ruby [1d]

Exercise 1: XML

On the start page of your Movie DB, show the title of a random movie that is coming soon to theaters.


Consider the best place to put the new logic. Should it be an existing class or a new class?

Exercise 2: JSON

Automatically ret...

328 Testing JavaScript with Jasmine [1.5d]

Jasmine is a great tool to unit test your JavaScript components without writing an expensive end-to-end test for every little thing.

Jasmine is a purely client-side tool. It cannot ask Rails to render a view or access the database. Any HTTP calls must be mocked.


What do we test with Jasmine?

Just as unit tests are a direct way to closely look at your classes, Jasmine is a very direct way to look at your JavaScript components.

For example, when you want to test that a date picker opens a calenda...

335 Secure storage of file attachments [2d]


  • Learn to store attachments in a way that is accessible by authorized users only
  • Learn to prevent users from uploading malicious content



Add the following feature to MovieDB:

  • Actors have a *contrac...

353 CSS Grids [2d]

If you've stumbled over display: grid while reading the Flexbox material of the previous card - we've got you covered!
Let's dive into this topic with a quote:

Flexbox is made for one-dimensional layouts and Grid is made for two-dimensional layouts.

You will learn more subtle differences in the linked material below, but you can remember this as a rule of thumb.


  • [A Complete Guide to CSS Grid](https://css-tricks.com/snippets/css/complete...

355 Requirements analysis and minimum viable UIs [3d]

Many of our clients can't or don't want to design their user interfaces. In the absence of a good UI design, you should always be able to come up with a default. Since the user interface makes up 70% of a typical web application, this is closely related to requirements analysis and cost estimation.


Talk with your mentor about the following topics:

  • Extracting nouns from requirements prose
  • Drawing ER diagrams and minimizing boxes
  • Why nouns from the client domain do not always map to Ruby models 1:1. E.g. only if a "address...

370 Bonus: Technology choice [0.5d]


Growing Rails applications in practice

Read the following chapters from our book Growing Rails Applications in Practice:

  • On following fashions
  • Surviving the upgrade pace of Rails
  • Owning your stack

Discuss each chapter with your mentor.

Being a good open-source citizen

Work through the follow resources:

372 Dealing with legacy applications [0.75d]

Adopting legacy Rails apps

Talk to your mentor about how we're approaching applications that are either old or abandoned by a different team earlier:

  • Add E2E tests for the happy path. Other than unit tests, E2E tests will not break when we refactor later.
  • Always add tests on whatever we work on.
  • When you work on something, improve that part of the code.
  • Make sure setup for a new developer is as frictionless as possible (ideally it's bundle && rake db:create db:migrate).
  • Make sure deployment is as frictionless as possible.
  • ...

385 Rack and Middlewares

Goal of this lesson is to understand what middlewares in Rack are good for.


Start with these articles:

You should be able to answer the following questions:

  • What is Rack?
  • How does Rack relate to Ruby on Rails?
  • What is Rack middleware?
  • What are some ...

395 Background processing [2d]

Some tasks in a web application are better not done live when a user request a page, but in the background. Examples are

  • longer running tasks
  • tasks that are not tied to user interaction
  • tasks that can fail, and may need to be retried

Our two main mechanisms for background processing are

Learn about cronjobs

  • Read [HowTo: Add Jobs To cron Under Linux or UNIX?](http:...

396 Internationalization (I18n) [2d]



397 Rails: Sending e-mail [2d]



  • In MovieDB, if you did not implement sending a welcome e-mail, send an e-mail now.
  • In MovieDB, whenever someone creates a movie, send a notification to `mo...

400 Bonus: Buzzwords and staying up to date [1d]

Web technology is a broad field and you cannot be an expert in all aspects.

However, it is useful to have a rough understanding of common terms and buzzwords, so that you don't seem uninformed when talking to a client or other developers.

Get an overview

Search the Internet for each of the following terms. Only take a couple of minutes for each and don't get into too much detail. Do get a rough idea about the advantages they promise.

  • Continuous Integration or CI
  • Single-Page Application or SPA
  • `Progressiv...

910 Bonus: Rake [0.75d]


  • What is rake good for?
  • Take a look at some of the Rake tasks that Rails gives you (rake -T within a Rails project)
  • Find the code that defines the rake stats task in the Rails gems
  • What are some ways how a Rake task can execute another task?
  • What does it mean if a Rake task "depends" on another task? E.g. understand what it means for a Rake task within a Rails app to depend on :environment.
  • Understand that Capistrano tasks are also defined using the Rake DSL, but a Capistrano task is not automatically a...

940 Bonus: Persisting trees [2d]

Storing a tree

For each movie in MovieDB, we want to track which other movie it was inspired by. For example:

  • "Interstellar was inspired by 2001"
  • "Inception was inspired by The Matrix"

Start by adding a field Movie#inspiration_id. In the movie form, I should be able to select the inspiring movie.

The list should:

  • include all the movies that were released in previous years
  • not include the movie itself
  • not include a movie that was itself inspired by the movie that is being edited.


In the...

985 Modern build pipelines with Webpack [3d]

Rails ships with two separate build pipelines: Sprockets ("asset pipeline") and Webpacker.

Webpacker has many more moving parts, but allows us to use ES6 modules and npm packages (through Yarn). Webpacker is a wrapper around a JavaScript project called webpack.


Yarn is the package manager we use for JavaScript. It does for JavaScript roughly what Bundler does for Ruby.

Read the first couple of sections of its official documentation.

You should learn how to:

  • Insta...

990 Static site generators


Talk with a colleague and find out why we're using building some of our sites using static site generators instead of Rails.

You should talk about:

  • Ease of development
  • Security issues and maintenance costs

Read through the Middleman docs:

  • What can it do?
  • What can't it do?
  • What parts do you know from Rails?


  • Checkout the repo for the makandra blog
  • Start the preview server
  • Make some changes, review them on localhost:4567...

995 Bonus: Images [1.5d]


Image formats

  • Understand the difference between raster images (like .png) and vector images (like .svg).
  • Understand why a print designer talks a lot about physical measurements like "cm" and "DPI" and why this rarely matters to us.
  • Understand how JPEG compression degrades the image quality every time you save the file.
  • Understand the strengths and weaknesses of the following file formats:
    • png
    • webp
    • gif
    • jpg
    • svg

High density displays

Browse the i...