3954 cards
Auto-destruct in 15 days

Unpoly 2.3.0 released

More control over loading Unpoly

  • Unpoly can now be loaded with <script defer>. This can be used to load your scripts without blocking the DOM parser.
  • Unpoly can now be loaded with <script type="module">. This can be used deliver a modern JS build to modern browsers only.
  • Unpoly can now be booted manually Archive at a time of your choice. By default Unpoly boots automatically once the initial DOM is parsed.
  • Event listeners registered with up.on() Archive will no longer be called bef...
Auto-destruct in 13 days

Unpoly 1.0.3 released

This maintenance release addresses two issues that were introduced in version 1.0.0:

  • Unpoly can now be loaded with <script defer>. This can be used to load your scripts without blocking the DOM parser.
  • Unpoly can now be loaded with <script type="module">. This can be used deliver a modern JS build to modern browsers only.
Linked contentAuto-destruct in 9 days

Updated: RSpec: Tagging examples and example groups


Note that RSpec will, although it prints your tags inclusion/exclusion config before the suite run, ignore tag config when you pass it a spec file with a line number. That's even when the line number references a describe or context block, where only some examples should be excluded.

Bookmarklet to facilitate generating new git branches for PivotalTracker Stories

This bookmarklet grabs a PivotalTracker story title, transforms it into a valid git branch name and automatically prepends your initials and an optional abbreviation (for better tab completion). It will output the following formats:

If you cancel the first dialog or confirm it without entering text:

git checkout -b kw/178298638-card-320-state-machines

If you enter an abbreviation (e.g. stm in this case):

git checkout -b kw/stm/178298638-card-320-state-machines

How to set it up:

  • in the attached file replace `YOUR_INITI...

Unobtrusive JavaScript helper to progressively enhance HTML

The attached compiler() function below applies JavaScript behavior to matching HTML elements as they enter the DOM.

This works like an Unpoly compiler Archive for apps that don't use Unpoly Archive , Custom Elements Archive or any other mechanism that pairs JavaScript with HTML elements.

The compiler() function is also a lightweight replacement for our legacy [$.unobtrusive()](https://makandracards.com/makandra/4-unobtrusiv...

Using inline event handlers with a strict Content Security Policy (CSP)

Given you have a strict CSP that only allows <script src> elements from your own domain:

Content-Security-Policy: script-src 'self'

This will block JavaScript handlers inlined into your HTML elements. Clicking on the following link will only log an error with a strict CSP:

<a href="javascript:alert('hello')">click me</a>
<a href="#" onclick="alert('hello')">click me</a>

Solution 1: Move the handler into your JavaScript

The recommended solution is to move the handler from the HTML to the allowed JavaScript fi...

Linked contentRepeats

RSpec: Debug flickering test suites with rspec --bisect

In modern default RSpec configurations, your tests are usually run in random order. This helps to detect "flickering" tests that only fail when run in a certain order.

The reason for this are tests that have side effects causing other tests to fail later. The hard part is to find the offending test.

Enter rspec --bisect:

  1. Say you have a flickering test that passes on its own, but you just saw it fail in a full test run. At the top of the RSpec output, you will see a message like Randomized with seed 12345. Take a note of the number....

How to use html_safe correctly

Back in the war, Rails developers had to manually HTML-escape user-supplied text before it was rendered in a view. If only a single piece of user-supplied text was rendered without prior escaping, it enabled XSS attacks Archive like injecting a <script> tag into the view of another user.

Because this practice was so error-prone, the rails_xss plugin Archive was developed and later integrated into Rails 3. rails_xss follows a different approach: Instead of relying...


Understanding database cleaning strategies in tests

TLDR: In tests you need to clean out the database before each example. Use :transaction where possible. Use :deletion for Selenium features or when you have a lot of MyISAM tables.

Understanding database cleaning

You want to clean out your test database after each test, so the next test can start from a blank database. To do so you have three options:

  • Wrap each test in a transaction which is rolled back when you're done (through DatabaseCleaner.strategy = :transaction or `config.use_transactional_fi...

MySQL: Careful when using database locks in transactions

We tend to use database transactions as a magic bullet to get rid of all our concurrency problems. When things get really bad, we might even throw in some locking mechanism, but then are usually done with it.

Unfortunately, transactions semantics in databases are actually very complicated, and chances are, your making some incorrect assumptions.

The MySQL innodb engine actually has [four different modes](ht...

Linked content

CSS has a well-supported :empty selector

All browsers + IE9 Archive know the CSS :empty selector. It lets you hide an element when it has no content, i.e. not even white space.

(How to prevent whitespace in HAML) Archive

For instance, you have a badge displaying the number of unread messages in a red bubble with white text:

.unread-messages-bubble {
  background-color: red;
  border-radius: 10px;
  padding: 10px;
  color: white;

To hide that bubble entirely whe...

Linked contentRepeats

Rails: Talking to the database without instantiating ActiveRecord objects

Instantiating ActiveRecord objects comes expensive. To speed up things, you can choose a more direct way to talk to your database: the ActiveRecord::ConnectionAdapters::DatabaseStatements Archive module.

Using the module and its methods is not suggested in the usual in-app workflow, as validations, callbacks, custom getters/setters etc. are ignored. However, for database-centered stuff like migrations, these fill the gap between writing pure SQL and full...


Howto: Elements to trigger Javascript

Often people need links which are not linked directly, but should trigger execution of javascript.

You can find a lot of workarounds for that:

  • <a href="#">Do something with js!</a>
    This defines an empty anchor. This may lead the browser to let the page jump to the top when the link is clicked. This is probably not what you want.

  • <a href="#!">Do something with js!</a>
    This tells the browser to jump to an anchor !. It depends on the browser implementation what happens when an anchor with unknown target ist clicked. In the bes...

Linked content

SSL/TLS - Typical problems and how to debug them

The linked article provides a description of commonly found problems with TLS and hints on debugging / solving them.


Don't forget: Automatically remove join records on has_many :through associations


# Given the following models

class Image < ActiveRecord::Base
  has_many :album_images
  has_many :albums, through: :album_images

class Album < ActiveRecord::Base
  has_many :album_images
  has_many :images, through: :album_images

# Join model
class AlbumImage < ActiveRecord::Base
  belongs_to :album
  belongs_to :image

Destroying a record in this setup will only remove the record itself, and leave orphaned join records behind.

image = Image.last
image.destroy # removes only the `image` record,

RSpec < 2.11: ActiveRecord scopes must be loaded before using the "=~" matcher

To test whether two arrays have the same elements regardless of order, you can use the =~ matcher in RSpec < 2.11:

actual_array.should =~ expected_array

If either side is an ActiveRecord scope rather than an array, you should call to_a on it first, since =~ does not play nice with scopes:

actual_scope.to_a.should =~ expected_scope.to_a

If you use RSpec >= 2.11 we recommend using the match_array or contain_exactly matchers instead of =~.
Use the eq matcher only if the order of records matters.

Default Arguments and Memoized

tl;dr: Avoid to memoize methods with default (keyword) arguments!

When you are using Memoized with default arguments or default keyword arguments, there are some edge cased you have to
keep in mind.

When you memoize a method with (keyword) arguments that have an expression as default value, you should be aware
that the expression is evaluated only once.

memoize def print_time(time = Time.now)

=> 2021-07-23 14:23:18 +0200

=> 2021-07-23 14:23:18 +0200

When you memoize a met...


CSS has a built-in clearfix

The need for clearfix hacks Archive has been greatly reduced since we could layout with Flexbox or CSS Grid.

However, when you do need a clearfix, there's no reason to use a hack anymore. You can just give the clearing container display: flow-root Archive .

This is supported by all browsers except IE11 Archive .

This website uses short-lived cookies to improve usability.
Accept or learn more