Controlling issue grouping in Sentry
When you use Sentry to monitor exceptions, an important feature is Sentry's error grouping mechanism. It will aggregate similar error "events" into one issue, so you can track and monitor it more easily. Grouping is especially important when you try to silence certain errors.
It is worth understanding how Sentry's grouping mechanism works.
The default grouping mechanism
The exact algorithm has changed over time, and Sentry will keep using the algorithm t...
Clean your Rails routes: grouping
In Ruby on Rails, all the routes of a given application can be found within the config/routes.rb file.
You add more and more routes in this file as your project grows.The problem here is that this file potentially becomes very complicated to manage over the time.
That’s why it’s important to find a way to order and maintain your routes.
See: Clean your Rails routes: grouping
Sometimes the routes.rb
grows very fast and each line adds mo...
Rails: How to get the ordered list of used middlewares
Rails middlewares are small code pieces that wrap requests to the application. The first middleware gets passed the request, invokes the next, and so on. Finally, the application is invoked, builds a response and passes it back to the last middleware. Each middleware now returns the response until the request is answered. Think of it like Russian Dolls, where each middleware is a doll and the application is the innermost item.
You can run rake middleware
to get the ordered list of used middlewares in a Rails application:
$> rake midd...
How to check if a file is a human readable text file
Ruby's File class has a handy method binary?
which checks whether a file is a binary file. This method might be telling the truth most of the time. But sometimes it doesn't, and that's what causes pain. The method is defined as follows:
# Returns whether or not +file+ is a binary file. Note that this is
# not guaranteed to be 100% accurate. It performs a "best guess" based
# on a simple test of the first +File.blksize+ characters.
#
# Example:
#
# File.binary?('somefile.exe') # => true
# File.binary?('somefile.txt') # => fal...
How to migrate CoffeeScript files from Sprockets to Webpack(er)
If you migrate a Rails application from Sprockets to Webpack(er), you can either transpile your CoffeeScript files to JavaScript or integrate a CoffeeScript compiler to your new process. This checklist can be used to achieve the latter.
- If you need to continue exposing your CoffeeScript classes to the global namespace, define them on
window
directly:
-class @User
+class window.User
- Replace Sprocket's
require
statement with Webpacker's...
Vortrag: Content Security Policy: Eine Einführung
Grundidee
CSP hat zum Ziel einen Browser-seitigen Mechanismus zu schaffen um einige Angriffe auf Webseiten zu verhindern, hauptsächlich XSS-Angriffe.
Einschub: Was ist XSS?
XSS = Cross Site Scripting. Passiert wenn ein User ungefiltertes HTML in die Webseite einfügen kann.
<div class="comment">
Danke für den interessanten Beitrag! <script>alert('you have been hacked')</script>
</div>
Rails löst das Problem weitgehend, aber
- Programmierfehler weiter möglich
- manchmal Sicherheitslücken in Gems oder Rails
Lösungsid...
Automatically validating dependency licenses with License Finder
"Open-source software (OSS) is great. Anyone can use virtually any open-source code in their projects."
Well, it depends. Licenses can make things difficult, especially when you are developing closed-source software. Since some OSS licenses even require the employing application to be open-sourced as well (looking at you, GPL), you cannot use such software in a closed-source project.
To be sure on this, we have developed a project-level integration of Pivotal's excellent [license_finder](https:/...
The HTML5 video element
# Basic HTML example
<video poster="preview_image.png" controls>
<source src="or_here.webm" type="video/webm" />
<source src="alternative_if_browser_cant_pay_first_source.mp4" type="video/mp4" />
<track src="optional_subtitles.vtt" kind="subtitles" srclang="de" label="Deutsch" default>
</video>
# Javascript API (notable methods and properties)
video = document.querySelector('video')
video.play()
video.pause()
video.load() // Reset to the beginning and select the best available source
video.currentSrc // The selected source
video.c...
HTTP Client in RubyMine
RubyMine has a HTTP Client that can be useful to test web APIs.
Just create a .http
scratch file an write your request in it.
The request can then be executed with the "Run all requests in File" button above the file.
Some alternatives:
The format for request is like this:
Method Request-URI HTTP-Version
Header-field: Heade...
Select2 alternatives without jQuery
Select2 is a fantastic library for advanced dropdown boxes, but it depends on jQuery.
Alternatives
Tom Select
There is a selectize.js
fork called Tom Select. It is well tested, comes with Bootstrap 3, Bootstrap 4 and Bootstrap 5 styles and is easy to use. You might miss some advanced features.
Known issues:
- Dynamic opt-groups in AJAX requests are not supported, you need to define them in advance on the select field (see <https://github.com/selectize/selectize.js/pull/1226/...
How to use Active Job to decouple your background processing from a gem
In a web application you sometimes have tasks that can not be processed during a request but need to go to the background.
There are several gems that help to you do that, like Sidekiq or Resque.
With newer Rails you can also use ActiveJob as interface for a background processing library. See here for a list of supported queueing adapters.
For ...
Howto: Select2 with AJAX
Select2 comes with AJAX support built in, using jQuery's AJAX methods.
...
For remote data sources only, Select2 does not create a new element until the item has been selected for the first time. This is done for performance reasons. Once an has been created, it will remain in the DOM even if the selection is later changed.
If you have a huge collection of records for your select2 input, you can populate it via AJAX in order to not pollute your HTML with lots of <option>
elements.
All you have to do is to provide...
Testing for XSS in Markdown Fields
If you render markdown from user input, an attacker might be able to use this to inject javascript code into the source code of your page.
The linked github page is a collection of common markdown XSS payloads which is handy for writing tests.
Producing arbitrary links:
[Basic](javascript:alert('Basic'))
[Local Storage](javascript:alert(JSON.stringify(localStorage)))
[CaseInsensitive](JaVaScRiPt:alert('CaseInsensitive'))
[URL](javascript://www.google.com%0Aalert('URL'))
[In Quotes]('javascript:alert("InQuotes")')
Using onload...
The ultimate guide to Ruby timeouts
An unresponsive service can be worse than a down one. It can tie up your entire system if not handled properly. All network requests should have a timeout.
Here’s how to add timeouts for popular Ruby gems. All have been tested. You should avoid Ruby’s Timeout module. The default is no timeout, unless otherwise specified. Enjoy!

Legacy CarrierWave: How to generate versions with different file extensions
We use CarrierWave in many of our projects to store and serve files of various formats - mostly images. A common use case of CarrierWave's DSL is to "process" the original file in order to create multiple "versions", for example different resolutions of the same image.
Now we could go one step further: What if we want to create versions that have a different file extension than the original file? For example, let's assume we'd like to create a ve...
Five years of "Today I Learned" from Josh Branchaud
The linked GitHub repository is a bit like our "dev" cards deck, but groomed from a single person (Josh Branchaud). It includes an extensive list of over 900 TILs on many topics that might be interesting for most of us. (e.g. Ruby, Rails, Git, Unix..)
Ruby
Here is an excerpt of all the Ruby TILs that were new to me. I encourage you to take your time to skim over the original list as well!
-
Assoc For Hashes
- `Hash#ass...
Rails: Concurrent requests in development and tests
With puma
you can have concurrent requests. There are two concepts on how Puma can handle two incoming requests: Workers and Threads.
Workers
Puma can have multiple workers. Each worker is a process fork from puma and therefore a very heavy instance and can have multiple threads, that handle the incoming requests.
Example: A Puma server with 2 workers
and 1 thread
each can handle 2 request in parallel
. A third request has to wait until the thread of one of the workers is free.
Threads
Rails is thread-safe since version 4 (n...
Test-Driven Development with integration and unit tests: a pragmatic approach
Test-Driven Development (TDD) in its most dogmatic form (red-green-refactor in micro-iterations) can be tedious. It does not have to be this way! This guide shows a pragmatic approach with integration and unit tests, that works in practice and improves on productivity.
Advantages
- No added effort: tests need to be written anyway.
- Test heads serve as todo lists. You'll always know what is finished and what is left to do.
- Big tasks are broken down into smaller tasks that can be processed one by one.
- You will not forget a test.
- You...
Bundler in deploy mode shares gems between patch-level Ruby versions
A recent patch level Ruby update caused troubles to some of us as applications started to complain about incompatible gem versions. I'll try to explain how the faulty state most likely is achieved and how to fix it.
Theory
When you deploy a new Ruby version with capistrano-opscomplete, it will take care of a few things:
- The new Ruby version is installed
- The Bundler version stated in the Gemfil...
Video transcoding: Web and native playback overview (April 2020)
Intro
Embedding videos on a website is very easy, add a <video>
tag to your source code and it just works. Most of the time.
The thing is: Both the operating system and Browser of your client must support the container and codecs of your video. To ensure playback on every device, you have to transcode your videos to one or more versions of which they are supported by every device out there.
In this card, I'll explore the available audio and video standards we have right now. The goal is to built a pipeline that...
Devise: How to allow only HTTP Basic Auth and disable the HTML sign-in form
By default, Devise redirects to a sign-in form when accessing a route that requires authentication. If for some reason you do not want this, but use Basic Authentication (and the corresponding browser username/password dialog) instead, this is a simple change.
Note that Devise's default configuration actually only redirects requests for HTML content (as requested by the HTTP Accept
header).
For all other formats (like JSON) it would use Basic Auth if the http_authenticatable
setting was enabled. So you can simply enable that flag and cl...
Heads up: Ruby's Net::HTTP silently retries a failing request
Ruby's Net::HTTP library repeats a failing request once, as long as it deems it idempotent (GET, HEAD etc). Both requests will use the configured timeout. Hence, if both requests time out, Net::HTTP will only return after twice the configured timeout.
This can become an issue if you rely on the timeout to strike precisely.
Letting a DOM element fade into transparency
You can use the CSS property mask-image
to define an "alpha channel" for an element.
E.g. to let an element start at full opacity at the top and gradually fade into transparency at the bottom:
.box {
-webkit-mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
mask-image: linear-gradient(to bottom, black 0%, transparent 100%);
}
- A fully opaque black pixel will render the masked pixel fully opaque
- A fully transparent black pixel will render the ...
Ruby: How to fetch a remote host's TLS certificate
TLS/SSL certificates are often used for HTTPS traffic. Occasionally a service may also use their TLS certificate to support public-key encrypting data (e.g. when it is part of the URI and visible to the user, but contains sensitive information).
Here is how to easily fetch such certificate data.
certificate = Net::HTTP.start('example.com', 443, use_ssl: true) { |http| http.peer_cert }
# => #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=www.example.org,...>
certificate.public_key
# => #<OpenSSL::PKey::RSA:0x...