Sidekiq: Problems and Troubleshooting
When using Sidekiq in your application, you must write thread-safe code.
This wiki page also lists gems that are known to be unsafe on threaded applications.
When adding a gem that will also be used by a Sidekiq worker, make sure to confirm it's thread-safe.
Caution when using the || operator to set defaults
I often see the use of ||
to set a default value for a variable that might be nil
, null
or undefined
.
x = x || 'default-value'
This pattern should be avoided in all languages.
While using ||
works as intended when x
is null or an actual object, it also sets the default value for other falsy values, such as false
. false
is a non-blank value that you never want to override with a default.
To make it worse, languages like JavaScript or Perl have [many more fal...
Caching in Rails < 6.1 may down parts of your application when using public cache control
Proxy caching is a good feature to serve your publicly visible application content faster and reduce load on your servers. It is e.g. available in nginx, but also affects proxies delivered by ISPs.
Unfortunately, there is a little problem in Rails < 6.1 when delivering responses for different MIME-types. Say you have an arbitrary route in your Rails application that is able to respond with regular HTML and JSON. By sending the specific MIME type in the Accept
header, you tell the application to either return HTML (text/html
) or JSON (`t...
Reverse lookup a fixture name by its id and table name
To reverse lookup a fixture by its table name and id, use the following approach on ActiveRecord::FixtureSet
:
table = 'users' # Specify the fixture table name
id = 123122 # Specify the ID to look for
# Find the fixture that matches the given ID
ActiveRecord::FixtureSet.all_loaded_fixtures[table].fixtures.find { |key, value| value['id'] == id }
Result Example:
[
"one", # Fixture name
#<ActiveRecord::Fixture:0x00007e79990234c8>, # ActiveRecord::Fixture object
@fixture= { ... }, # The raw fixtu...
Updated: Sass: How to get rid of deprecation warnings in dependencies
I tried to make it easier to read how to set the sass options for the different build tools.
Updated: How to allow testing beforeunload confirmation dialogs with modern ChromeDrivers
Updated for selenium-webdriver 4.27 which requires options.add_option(:page_load_strategy, 'none')
.
NPM: How to verify that your package-lock.json fulfills dependencies of package.json
Your package-lock.json
should always match and resolve all packages from your package.json
.
Coming from Yarn, I was looking for an option like Yarn's --frozen-lockfile
which validates that. Here is what seems to be the way to do it.
Using npm clean-install
Running npm clean-install
instead of npm install
will actually validate that your package-lock.json
matches your package.json
.
You can use npm ci
as a shortcut for npm clean-install
.
Combine with a cache
The idea of a "clean install" is that it always install...
Understanding `safe_constantize` in Rails
Warning
safe_constantize
is not safe for unfiltered user input
In Rails, the safe_constantize
method is a powerful tool that helps developers safely convert strings into constants. This feature is particularly useful in scenarios where constant lookup might fail or could potentially introduce security risks. Let’s dive into what safe_constantize
is, how it works, and why you should use it.
What Is safe_constantize
?
The `safe_cons...
How to disable logging for ActiveStorage's Disk Service routes
In development, we store files using ActiveStorage's disk
service. This means that stored files are served by your Rails application, and every request to a file results in (at least!) one non-trivial log entry which can be annoying. Here is how to disable those log entries.
Example
Here is an example of what loading a single <img>
in an example application writes to the Rails log.
Started GET "/rails/active_storage/blobs/redirect/..." for ::1 at ...
Processing by ActiveStorage::Blobs::RedirectController#show as SVG
Parameter...
Ignore Selenium driver deprecations
If you update Selenium regularly, you'll run into deprecation warnings similar to:
WARN Selenium [:clear_local_storage] [DEPRECATION] clear_local_storage is deprecated and will be removed in a future release
You can ignore this deprecation warning and clean your logs with logfilters:
Selenium::WebDriver.logger.ignore(:clear_local_storage)
Just specify the tag (:clear_local_storage
) you want to ignore.
PSA: Umlauts are not always what they seem to be
When you have a string containing umlauts which don't behave as expected (are not matched with a regexp, can't be found with an SQL query, do not print correctly on LaTeX documents, etc), you may be encountering umlauts which are not actually umlaut characters.
They look, depending on the font, like their "real" umlaut counterpart:
- ä ↔ ä
- ö ↔ ö
- ü ↔ ü
However, they are not the same:
'ä' == 'ä' # false
'ä'.size # 1
'ä'.size # 2
Looking at how those strings are constructed reveals what is going on:
'ä'.unpack('U*...
How to combine "change", "up", and "down" in a Rails migration
Rails migrations allow you to use a change
method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE
statements) you can not define up
and down
methods at the same time.
If you were to define define all 3 of them, Rails would only run change
and ignore up
and down
. However, Rails 4+ features a helper method called reversible
:
class MyMigration < ActiveRecord::Migration
def cha...
RubyMine users: you should be using bookmarks
RubyMine allows bookmarking lines of code. This is super-helpful when working on a complex problem.
I've been using this feature for a few years now, and so should you! :)
Here are the default Linux/Windows keystrokes. See the documentation for other keybindings.
Add an anonymous bookmark
F11
A gray checkmark will be shown in the gutter on the left.
If you press F11
again on a bookmarked line, the bookmark will be removed.
Add a named bookmark ("mnemonic")
Ctrl
...
How the Date Header Affects Cookie Expiration and Caching
tl;dr
When a cookie includes an
Expires
attribute or an HTTP response includes caching headers likeExpires
orCache-Control
, their validity depends on the server'sDate
header if present. Otherwise, the browser uses its local time. This can lead to issues in tests with mocked time or inconsistent cache behavior.
Cookie Expires
depends on the Date
header or browser time
When a cookie includes an Expires
attribute, the browser evaluates the expiration date relative to a reference time:
- If the HTTP response ...
How to enable Rails' file_fixture helper in FactoryBot
In FactoryBot factories, Rails' file_fixture
is not available by default. To enable it, include a support module from rspec-rails:
FactoryBot::SyntaxRunner.include(RSpec::Rails::FileFixtureSupport)
That includes ActiveSupport::Testing::FileFixtures
, where file_fixture
is defined, but also configures the file_fixture_path
so that you can actually use file_fixture
.
Description list support (Updated: List of Helpful RubyMine Shortcuts)
Team C enabled support for description lists in makandracards.
Please make sure to add a newline before the definition starting with colon (:
).
Usage example:
Apple
: A fruit that grows on trees.
Orange
: A citrus fruit known for its vitamin C content.
More details in second paragraph.
will result in:
- Apple
-
A fruit that grows on trees.
- Orange
-
A citrus fruit known for its vitamin C content.
More details in second paragraph.
Updated: Breaking changes for boolean attributes in HAML 6
Updated most aspects of this card.
RSpec: Scoping custom matchers to example groups
When you find yourself in the situation that you would like to define a custom matcher in your specs, but you do not want to define a global matcher since you need it only for your specific test, there are two ways to do it:
Custom matcher for a single group
If you're only going to include
a matcher once, you can also use the matcher
macro within an example group:
describe "group" do
matcher :be_just_like do |expected|
match {|ac...
How to tackle complex refactorings in big projects
Sometimes huge refactorings or refactoring of core concepts of your application are necessary for being able to meet new requirements or to keep your application maintainable on the long run. Here are some thoughts about how to approach such challenges.
Break it down
Try to break your refactoring down in different parts. Try to make tests green for each part of your refactoring as soon as possible and only move to the next big part if your tests are fixed. It's not a good idea to work for weeks or months and wait for all puzzle pieces ...
Getting permanent links to files on Github or Gitlab
Please don't simply copy line number links from Github. The URL usually contains a branch name like master
which will change over time:
https://github.com/makandra/upjs/blob/master/lib/assets/javascripts/up/link.js.coffee#L76
If someone now posts an insertion or deletion to that file into master
your link points to the wrong line!
A better way is to press the Y
key after clicking on a line number. This will transform the URL to another URL that points to the particular commit:
https://github.com/makandra/upjs/blob/b3b14...
TestProf II: Factory therapy for your Ruby tests—Martian Chronicles, Evil Martians’ team blog
Some key highlights and points from the linked article TestProf II: Factory therapy for your Ruby tests.
The Problem with Factories in Ruby Tests
- Factories are used to easily generate test data.
- However, they can unintentionally slow down test suites by creating unnecessary or excessive associated data (factory cascades).
Understanding Factory-Induced Slowdowns
- Factories often create additional data (e.g., associated records) th...
Fragment Caching in Rails 7.1+ requires Haml 6
Rails slightly changed the fragment cache implementation from Rails 7.0 to Rails 7.1. Unfortunately, this is incompatible with how Haml 5 patches Action View buffers. I tried turning a String
buffer into an ActionView::OutputBuffer
, but this brought up...