000 Start here! [0d]
makandra offers an 8 month paid trainee program 🇩🇪 for junior developers that are looking to start a professional career in web development.
This curriculum contains goals, resources and code exercises for our trainees. If you haven't joined us yet, it offers you a glimpse of what you will learn!
Organizing your code
Push all your work to a GitLab repository, at least once per day. You can create unlimited repositories in personal your namespace, e.g. your.name/moviedb
.
When an ex...
105 Ruby basics [2d]
Ruby is the programming language we use on the backend.
Goals
After finishing this lesson you should be able to read and write simple Ruby programs.
Gain an understanding of the following concepts:
- Working with basic datatypes:
String
,Integer
,Float
,Boolean
,Array
,Hash
- Control flow:
if
,each
,case
,break
... - Functions:
def
,return
, implicit return in methods and blocks - Errors,
raise
andrescue
- Classes and inheritance
- The difference between class methods and instance methods (`def self.meth...
110 Where to find API documentation [0.5d]
There is no single place to look up documentation for our stack.
This card includes some hints where you can find API documentation. You probably want to drag a few of those links to your bookmarks toolbar. This will help in the upcoming exercises.
Ruby
Basic classes like String
, Error
, Hash
or Object
are part of the Ruby standard library:
- DevDocs for Ruby 3.3: Pretty web interface for the Ruby standard library
- RubyDoc for Ruby 3.3: Official docs for the Ru...
120 Git basics [1d]
Git is our version control system.
Goals
- Understand why we use
git
. - Learn how to work with your local repository:
- Create a local repository (
git init
) - Commit changes (
git add
,git commit
) - See the history (
git log
) - See changes (
git diff
) - Work with branches
- Create new ones:
git switch --create
orgit checkout -b
. - Switch to existing branches:
git switch
orgit checkout
- Combining history:
git merge
- Create new ones:
- Work with the stash
git stash
- Create a local repository (
- Learn how to...
125 Gems, bundler, rbenv [1d]
makandra is responsible for maintaining about 75 Ruby projects. These projects use a large number of different versions for Ruby, Rails and many gems. To be able to switch between projects easily, we must control every dependency our applications has.
Goals
- Understand what a gem is
- Learn how to install a gem
- Be able to look into gem code
- locally
- on GitHub
- Learn about Bundler
- Why is it necessary:
- Managing versions and dependencies
- Defining a consistent project environment
- What is the difference bet...
- Why is it necessary:
130 Ruby on Rails basics [4d]
Rails is our web framework.
Goals
- Be able to write a simple Rails application.
- Understand how Rails talks to the database (
ActiveRecord
)- What is a model?
- How are records retrieved and saved?
- Validations
- Migrations
-
belongs_to
,has_many
,has_many :through
- Gain an understanding of the structure of a basic Rails app
- Routes
- Controllers
- Generate a controller using Rails scaffolding
- Write your own controller
- Views
- using
ERB
- using
- Models
- Helpers
- Learn how to do CRUD ("Crea...
140 Testing basics [3.5d]
Goals
- Understand why we test:
- Low defect rate without a QA department.
- Customer acceptance testing can concentrate on new features and things a robot cannot do (e.g. how does a feature look and feel).
- Frequent deploy gets changes to users faster.
- We sleep better, because we know stuff still works.
- Make sure no one removes a feature by accident.
- Ability to change one part of an application without needing to understand the entire system.
- Why do we use different types of tests?
- What are the pros and cons ...
141 Creating test data with factories [1d]
Goals
- Learn to create test data effectively using factories.
- Decouple tests by having each test start with an empty database and create only the records needed for the test.
Learn
Factories, not fixtures
By default Rails uses global fixtures for its tests. This is a giant world of example data that grows with every test.
In our experience the use of fixtures can make a test suite hard to work with. In any non-trivial test suite th...
142 Validations [1d]
Basic validations
Read the Rails Guide on ActiveRecord Validations. You should have an overview which kinds of validations are built into Rails.
Also read Testing ActiveRecord validations with RSpec.
Make the following changes to your MovieDB:
- Make sure your MovieDB models have validations for all required fields.
- Make sure you have specs for all your validations ...
145 CSS basics [3d]
Goals
- Understand at least the following CSS concepts:
- Classes
- Selecting elements for styling
- Basic styling (color, typography, spacing)
- The box model
- Inline elements vs. block elements
- Ways to layout elements
- Learn how to use your browser's "inspect" feature and how you can see which CSS styles are applied to an element
- Learn what a "reset stylesheet" is.
- Learn what "CSS precompilers" are. Examples are "Sass" and "Less" (we use "Sass").
- Learn some basic Sass syntax:
- Variables
- Nesting
- Parti...
150 JavaScript basics [2d]
JavaScript is a scripting language supported by all browsers. Browsers don't speak Ruby, so if we want to implement client-side logic that runs in the browser, we need to express ourselves in JavaScript.
Goals
You should have a strong understanding of the following language features/concepts:
- Writing and reading variables
- Defining and calling functions
- Control flow:
if
,for
,switch
, ... - Functions and function pointers
- Iterating over lists
- Throwing and catching errors
- The arcane rules around
this
.
Coming from Ruby ...
152 Working with the DOM [1.5d]
JavaScript code can access and manipulate the browser's DOM tree. Using JavaScript we can add interactive behavior to our interfaces that would not be possible through declarative rules in HTML and CSS alone.
Goals
Know how to use the native DOM API to do the following:
- Selecting all elements matching a given CSS selector
- Selecting all descendants of a given element matching a given CSS selector
- Registering event listeners
- Changing an element'...
154 Haml [0.5d]
Goal
- Learn to read and write Haml.
- Understand the different attributes syntaxes (curly braces vs. round parentheses)
Exercises
- Convert MovieDB from ERB to Haml
Hint
The Haml-tutorial doesn't show how to execute ruby-code that isn't rendered to HTML. To do this start a line with a dash ('-') instead of the equals-sign ('=').
165 ActiveRecord scopes [4d]
In this card we will learn to write code that scales with a large number of database records. We will do this by pushing work out of Ruby and into the database.
Goals
- Understand what scopes ("relations") are and how they differ from arrays.
- Understand how a purely object-oriented approach of processing data doesn't scale for a large number of database records.
- Get into a habit of off-loading list-related calculations (filtering, mapping) to the database. Only fetch an ActiveRecord objects from the database when you actually pla...
167 Software design basics [4d]
Reading
Read the following chapters from The Pragmatic Programmer, anniversary edition (in our library):
- Chapter 1, Topic 3: Software Entropy
- Chapter 2, Topic 9: The Evils of Duplication
- Chapter 2, Topic 10: Orthogonality
- Chapter 5, Topic 28: Decoupling (and the Law of Demeter)
Read the following chapters from Clean Code (in our library):
- Chapter 1: Clean Code
- Chapter 2: Meaningful Names
- Chapter 3: Functions
- Chapter 4: Comments
- Chapter 5: Formatting
- Chapter 8: Boundaries
- Chapter 10: Classes
- Chapter 12:...
170 Memoization [0.4d]
Goals
- Understand what Memoization is and when it can be useful.
- Understand the
@variable ||= computation
pattern. - Learn how to use the memoized gem.
- What are the advantages of a gem like
memoized
over the@variable ||=
syntax? - Why can it be dangerous to memoize class methods?
Why is it often fine to memoize instance methods?
Resources
- Speeding up Rails with Memoization
- [4 Simple Memoization Patterns in ...
172 Debugging [1d]
When your code does not behave as expected, you can use a debugger statement ("breakpoint") at any point in your code. This statement will open a REPL ("console") that you can use to inspect the current state of the program and move the control flow ahead manually.
Use debugging tools to find the exact line in the code where your expectation does not match the actual behavior. Since we use open source for everything, we can always find that line. When you ask a colleague ...
175 RSpec in depth [2d]
Matchers
Built-in matchers
Get an overview of all the matchers that are built into RSpec.
Play with some of these matchers in your MovieDB tests.
The benefits of using better matchers
Which of the following two lines is better? Why?
expect(array).to include(5)
expect(array.include?(5)).to eq(true)
Custom matchers
Write a custom matcher called `have_sam...
180 Personal productivity [1d]
As developers we are dealing with many tasks every week. We need a system to organize ourselves.
Goals
After completing this card you should have:
- A to-do list that you maintain every day. Many of us use Holly, but a
todo.txt
on your desktop or any other tool is fine, too. - A habit of tracking any incoming task. We can never forget a task that a colleague or customer gives us.
- A habit of splitting any kind of task or project into actionable first steps.
- A habit of fully completing tasks to clea...
185 Our process [2d]
makandra's development process
Learn about our process. The squares represent the state of the issue in Linear:
In particular you should understand:
- Why do we have a process?
- What is an issue (formerly: story)?
- What metrics does our process optimize for?
- How to divide large requirements into issues. When is an issue too small, when is it too large?
- The lifecycle of an issue
- How to write an issue
Issue format
Read the card [Project mana...
186 Linux basics [1d]
Resources
- Learn Enough Command Line to be Dangerous (it's in our library => Google Drive)
- CLI tricks every developer should know
- Install the
tldr
tool usingsudo apt install tldr
. You can then get usage examples for every console command, e.g.tldr ssh
to get examples for thessh
command. (If there are no entries, runtldr -u
...
187 Exception notifications [0.5d]
- Understand how we're dealing with exception notifications.
- Integrate exception notification into your MovieDB. Use your personal e-mail as the notification target for now. You can omit any references to sidekiq for now.
- Trigger an error in MovieDB and receive the notification.
- Ask a colleague to show you how their SWAT teams deals with exception notificatio...
190 Pagination [0.5d]
Goals
- Understand why we use pagination
Exercises
- Create 7500 movies in MovieDB (hint: Doing it in a single transaction is much faster). Load the movies index and measure how long it renders.
- Use the
will_paginate
gem to add pagination to MovieDB's list of movies. How long does the movies index render now? - Inspect the HTML generated by
will_paginate
. Customize the style so it matches the look of your MovieDB. -
tail -f log/development.log
and see which querieswill_paginate
generates. What do they do?
200 Migrations [2d]
Reading
- Read the Rails Guide about Active Record migrations
- Understand why we never use models in migrations.
- Checkout the repository Project Hero and read through some migrations in
db/migrate
. Find two complex migrations and discuss them with your mentor.Tip
Find the largest files in the
db/migrate
folder. - Read and understand [How to write comp...