205 Basic file uploads and image versions [2d]
Goals
- Learn to treat files as an ActiveRecord attribute type, like
:string
or:integer
Research
- Look at the README for the carrierwave gem
- Read about Common mistakes when storing file uploads with Rails
- Carrierwave: How to attach files in tests
- [Carrierwave: Built-in RSpec mat...
210 Cucumber in depth [2d]
Advanced cucumber features
Learn about the following cucumber features:
- Doc Strings ("multiline strings")
- Tables
- Tags
- Before/after hooks
- Background
- [Scenario outlines](https://cucumber.io/docs/gherkin/reference/#sce...
215 Browser automation with Capybara and Selenium WebDriver [2d]
We use Selenium WebDriver integrated with Cucumber/Capybara for full-stack integration testing.
Try and use it
Your forked MovieDB should already include a feature that uses a real browser. Add the @javascript
tag to your other features to test it yourself.
When you run your cucumber feature now with NO_HEADLESS=1 geordi cucumber
, you should see a browser opening. Get someone to help you if this does not work.
Some of your features might now fail. You might find solutions below:
Making ...
224 Advanced git [2d]
Goals
- Understand the differences between
git diff
andgit diff --staged
(orgit diff --cached
) - Understand the difference between
git reset
andgit reset --hard
- Use
git add -p
- Use
git checkout -p
- Note you can also rollback partial changes from the line gutter in RubyMine.
- Use
git rebase -i
- Understand what it means for pushing to a remote, and for working with your colleagues
- Use
git rebase --onto
. - What do...
225 Event bubbling and delegation [1.5d]
Learn
You have the following HTML structure:
<div class='some-class'>...</div>
<div class='container'>
<div class='my-target'>...</div>
<div class='my-target'>...</div>
<div class='my-target'>...</div>
</div>
<div class='other-class'>...</div>
If you want to run Javascript code whenever someone clicks on a <div class='my-target'>...</div>
, you can do this in three different ways:
function code(event) {
alert("Someone clicked on .my-target!");
}
document.addEventListener('click', function(event) {
if...
230 Unobtrusive JavaScript components [3d]
Intro
A common task in web applications is to add client-side JavaScript behavior to existing HTML elements.
For instance, in Working with the DOM you built a movie counter script that's used like this:
<table>
<tr>...</tr>
<tr>...</tr>
</table>
<!-- Clicking shows the number of <tr> elements above -->
<button class="movie-counter">Count movies</button>
Your implementation probably looked like this:
window.addEventListener('DOMContentL...
235 Cookies and Rails Sessions [1d]
Learn
- What is a Cookie? Google it if you do not know.
- How are cookies transferred between your browser and the server?
- Open the development tools in your browser for this page. Can you find the cookies your browser stores for makandracards?
- In the network tab, can you see how the cookies are transferred to or from the server?
- Can you log yourself out by manipulating a cookie? Can you log yourself back in?
- Understand what domains mean to cookies
- Can cookies be shared between domains?
- Between subdomains?
- How...
237 Web application security [4d]
Web security basics
Einführung in die Web Security 🇩🇪 provides essentials for the topic of this card.
Read following chapters:
- (1) Security Principles
- (3.3) Sessions and Cookies
- (3.5) Same-Origin-Policy
- (4.2) Angriffsfläche / Attack Surface
- (4.3) Speicherung von Passwörtern
- (6) Kryptographische Grundlagen
- (7) Authentifikation
- (8) Authorization
- (9) Session Management
- Ohne (9.4) JSON Web Tokens
- (10) Federation / Single-Sign on
- (11) Serverseitige Angriffe
- (12) Clientseitige Angriff...
240 Authentication [3d]
Authentication is all about being able to verify the identity of a user in the context of our application.
While you could roll out a custom authentication solution, this would likely expose you to the various risks of "homegrown crypto". In practice we are using popular authentication libraries like clearance or devise for this task.
Learn
- Read the article [Rails Authentication from Scratch](https://stevepolito.design/blog/rails-authentication-fro...
245 Authorization [2.5d]
Reading
- Watch Solving bizarre authorization requirements with Rails
- Read the Consul README
- Read the assignable_values README
Understand how Consul and assignable_values can be used to implement arbitrary authorization systems.
Exercise: Read code
- In Cards, users can be given deck-specific read/write access. Play around in the cards UI to see that functionality.
- H...
247 Nested forms [2d]
Goals
- Understand how nested attributes appear in the params.
- See how the Rails form helpers encode the names of nested inputs.
- Understand how the record and all of its nested attributes are saved in a transaction. That means the entire structure is saved or not.
Resources
- Rails Guide: Nested forms
- Nested Forms in Rails
- [Popular mistakes when using nested forms](https://makandracards...
250 Form models [2d]
Reading
Read (or re-read) the following chapters from our book Growing Rails Applications in Practice (it’s in our library):
- New rules for Rails
- Beautiful controllers
- Relearning ActiveRecord
- User interactions without a database
- Creating a system for growth
- Dealing with fat models
- A home for interaction-specific code
- Extracting service objects
- Organizing large codebases with namespaces
Note
We're no longer using the
As
naming convention when extending mo...
255 Parsing text with regular expressions [1d]
Learn
Resources
- RubyGuides: Mastering Ruby Regular Expressions
- Using regular expressions in JavaScript
- Testing regular expressions visually
- Regular Expressions: Quantifier modes
- [Ruby: You can nest regular expressions](https://makand...
260 Network basics [0.5d]
HTTP
- How do HTTP requests and responses look like? What are HTTP headers? What are they used for?
- Look at real-life HTTP exchanges:
- Open makandra.com
- Open the Network tab of your browser inspector.
- Reload the page.
- Inspect each request and look at its request headers, response headers and payloads.
- What is HTTP/2?
Digging deeper
- Use
curl
to save a copy ofhttp://www.sueddeutsche.de/
. - Use
curl
to save the CSS stylesheet of sueddeutsche.de
SSL / TLS
------------...
270 More Software design [2d]
Software engineering principles
Read about the following software engineering principles and code smells:
- Single Responsibility Principle
- Law of Demeter
- Object Orgy
- Feature Envy
- Refresher: [Tell Don't As...
275 The HTML5 platform [1.5d]
Goals
- Get an idea of the varying support for HTML/CSS/JavaScript features in different browsers like Chrome, Firefox, Internet Explorer, Edge, Safari.
- Look up a few modern features like "subgrid", ":has()" or "optional chaining" on Caniuse.
- Understand how we test for older browsers using BrowserStack
- Ask a colleague for our shared BrowserStack credentials
- What are "Evergreen browsers"?
- Understand which browsers you are supposed to support in a project
- For most...
285 Frontend build pipelines in Rails [3d]
While working on a Rails application, your code base will grow a collection of different file types including:
- Ruby (business logic)
- HTML fragments (layouts and views)
- CSS/Sass/SCSS (styles)
- JavaScript (client-side behavior)
- Static media (images, fonts, videos)
Except for the Ruby part, all these files are shipped to the browser. In this card we'll focus specifically on CSS, JS, fonts and static media files which are often summed up as assets.
You might already have noticed that Rails modifies those assets before delivering ...
287 The asset pipeline [1d]
The asset pipeline is one of Rails' two mechanisms how stylesheets, javascripts and images from your /assets
folder are processed and delivered to the browser. Rails has a second pipeline called webpacker, which we will cover later.
Learn
- Read Everything You Should Know About the Rails Asset Pipeline
- Read [How to make your application assets cachable in Rails](/makandra/11345-how-to-make-your-...
288 50% Milestone
Congratulations, you just made it through about half of our curriculum deck! 🎉
We've covered the basics of your future stack and are about to dive deeper in some more advanced topics.
A few things before you move on
- Add a reminder to your calendar: Read 5 repeating cards every morning
- Add a reminder to your calendar: Repeat the learnings of the last 10 curriculum cards every other monday
- Read the article "[Parting advice from an older Software Engineer](
https://www.si...
290 Structuring CSS with the BEM pattern [4d]
We are using the BEM pattern ("Block, Element, Modifier") to structure our CSS in all new projects. We try to migrate legacy projects to BEM, block-by-block.
Read
Read the chapter "Taming Stylesheets" from our book Growing Rails Applications in Practice (in our library).
Talk with a colleague about the reasons for the naming conventions we ...
295 Advanced JavaScript [2.5d]
Stepping forward from JavaScript Basics, the goal of this card is for you to be able to read and write more complex ES6+ code.
The JavaScript Object Model
- Read The JavaScript Object Model: A deep dive into prototypes and properties.
- There's also a video of that talk in our internal library.
- The first three sections of the article [Inherita...
300 JavaScript: Writing asynchronous code [2.5d]
Reading
Understand how asynchronous JavaScript works:
- Read Henning's presentation about asynchronous Javascript (there's also a German video presentation in our shared folder)
- Read about Promises on MDN and [this visualization](https://www.lydiahallie.com/bl...
301 Using external JavaScript libraries [1.5d]
Just like we use gems on the server, we use third party JavaScript libraries in the browser. These typically provide functionality like:
- General support libraries like Lodash
- Frontend Frameworks like Unpoly
- Wysiwyg (What You See Is What You Get) HTML editors
- Datepickers
- Sliders
- Tooltips
- Dialogs
- ...
We generally use the yarn add
command to add third party libraries to our application. It will persist the desired library version within the package.json
file and pin matching d...
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...