Specify Gemfile for bundle

Bundler allows you to specify the name of the Gemfile you want to bundle with the BUNDLE_GEMFILE environment variable.

BUNDLE_GEMFILE=Gemfile.rails.7.2 bundle

By default, bundler will look for a file called Gemfile in your project, but there may be cases where you want to have multiple Gemfiles in your project, which cannot all be named Gemfile. Let's say for example, you maintain a gem and want to run automated tests against multiple rails versions. When you need to bundle one of your secondary Gemfiles, the solution above ...

Rails console tricks

Also see the list of IRB commands.

Switching the context

Changes the "default receiver" of expressions. Can be used to simulate a "debugger situation" where you are "inside" an object. This is especially handy when needing to call private methods – just invoke them, no need to use send.

  • Switch to an object: chws $object
  • Reset to main: chws
  • Show current context: cwws (usually shown in IRB prompt)

[Technical details](https://technology.doximity.com/articles/the-hidden-gems-of-r...

Does <html> or <body> scroll the page?

Scrolling overflowing elements with JavaScript

HTML elements with overflow-y: auto or overflow-y: scroll will get a scrollbar when their content is higher than their own height.

When you scroll an element , the element's scrollTop property is updated with the scrollbar's new position. You can also set element.scrollTop = 30 to scroll the element to a vertical pixel position counted from the top.

Scrolling the main viewport with JavaScript

The browser's main document viewport is also scrollable by default. The element that ...

Cucumber features as documentation

Cucumber allows for prose in features and scenarios. Example:

Feature: Cancel account

  There are several ways to cancel a user account. Admins need to 
  do it in complex cases, but normally, users can do it themselves.
  
  Scenario: User cancels his own account
    
    Users should be able to cancel an account themselves, so the 
    admins do not need to do it.
    
    Given a user account for "willy@astor.de"
    When I sign in as "willy@astor.de"
    And I follow "Cancel account"
    Then I should see "Account canceled"...

An auto-mapper for ARIA labels and BEM classes in Cucumber selectors

Spreewald comes with a selector_for helper that matches an English term like the user's profile into a CSS selector. This is useful for steps that refer to a particular section of the page, like the following:

Then I should see "Bruce" within the user's profile
                                 ^^^^^^^^^^^^^^^^^^

If you're too lazy to manually translate English to a CSS selector by adding a line to features/env/selectors.rb, we already have an [auto-mapper to translate English into ...

Updated: Capybara: Running tests with headless Chrome

Chrome is now kept from opening PDF downloads. It will stay on the current page.

Updated: Capybara: Running tests with headless Chrome

Updated for recent versions of Chrome, which do not have a "remote debugging address" and only listen on localhost.

Disable automatic code suggestions in RubyMine

To disable the mostly useless automatic suggestion popups in RubyMine, go to File / Settings, then to Editor / General / Code Completion and uncheck Auto-display code completion.

You can still open the popup by pressing CTRL + Space. And you probably want to use Context-dependent word expansion instead, anyway.

Why am I getting different results working with SVG files and ImageMagick?

When you are working with SVG files and ImageMagick you can get different results on different machines depending on which additional packages you have installed.

From: http://www.imagemagick.org/script/formats.php

ImageMagick utilizes inkscape if its in your execution path otherwise RSVG. If neither are available, ImageMagick reverts to its internal SVG renderer.

Git: How to stage hunks with a single key press

In interactive commands, Git allows the user to provide one-letter input with a single key without hitting enter (docs).

# Enabled this feature globally
git config --global interactive.singlekey true

# Or enable this feature locally for a single repository
git config interactive.singlekey true

This allows you to hit "y" instead of "y + ENTER" to move to the next hunk.

Stage this hunk [y,n,q,a,d,s,e,?]?

Building web applications: Beyond the happy path

When building a web application, one is tempted to claim it "done" too early. Make sure you check this list.

Different screen sizes and browsers

Desktops, tablets and mobile devices have all different screen resolutions. Does your design work on each of them?

  • Choose which browsers to support. Make sure the page looks OK, is usable and working in these browsers.
  • Use @media queries to build a responsive design
    • If you do not suppo...

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 like injecting a <script> tag into the view of another user.

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

Rails I18n fallback locales

When you need to create a locale for a language variant (like Austrian for German), you probably don't want to duplicate your entire de.yml file only to change a few minor exceptions for our Austrian friends.

Luckily, the I18n gem used by Rails has a fallback feature where you can make one locale file fall back to another if no translation is available.

In the example above you would have a config/locales/de_DE.yml:

de_DE:
  # hundreds of translations here

... and another...

Unpoly: Showing the better_errors page when Rails raises an error

When an AJAX request raises an exception on the server, Rails will show a minimal error page with only basic information. Because all Unpoly updates work using AJAX requests, you won't get the more detailled better_errors page with the interactive REPL.

Below is an event listener that automatically repeats the request as a full-page load if your development error shows an error page. This means you get...

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.