View

How to generate GIDs from an ActiveRecord scope

ActiveRecord provides the ids method to pluck ids from a scope, but what if you need to pluck Global IDs?

While you could just call map(&:to_global_id) on your scope, this approach would instantiate each record just to do that. When you have many records, this will at the very least be slow.

Here is a method that does it for you efficiently. It respects Single Table Inheritance (STI).
Put it in your project's ApplicationRecord to make it available on all models.

class ApplicationRecord
  ...
Repeats

Ruby: How to determine the absolute path relative to a file

If you want to get the path of a file relative to another, you can use the expand_path method with either the constant __FILE__ or the method __dir__. Read this card for more information about __FILE__ and __dir__.

Example

Structure:

.
├── bin
│   ├── format_changelog
├── CHANGELOG.md

bin/format_changelog:

#!/usr/bin/env ruby

changelog_path = ? # How to get the path to ../CHANGELOG.md independent of the working dir of the caller
changelog = File.read(changelog_path)

# ... further actions h...

Git: Search for text in all branches

To find a version containing the regular expression foo in the history of any branch:

git grep foo $(git rev-list --all)

You may also limit the search to a file extension, e.g. Ruby files (.rb) like this:

git grep foo $(git rev-list --all) -- *.rb
Linked content

Ruby Jard: Just Another Ruby Debugger

Ruby Jard provides a rich Terminal UI that visualizes everything your need, navigates your program with pleasure, stops at matter places only, reduces manual and mental efforts.

Repeats

How to make your application assets cachable in Rails

Note: Modern Rails has two build pipelines, the asset pipeline (or "Sprockets") and Webpacker. The principles below apply for both, but the examples shown are for Sprockets.


Every page in your application uses many assets, such as images, javascripts and stylesheets. Without your intervention, the browser will request these assets again and again on every request. There is no magic in Rails that gives you automatic caching for assets. In fact, if you haven't been paying attention to this, your application is probabl...

Linked contentRepeats

Nested ActiveRecord transaction pitfalls

When working with custom transactions and use ActiveRecord::Rollback you may encounter unexpected behaviour if you try to roll back your changes.

tl;dr

Not all databases support nested transactions. Therefore, Rails will sometimes silently ignore a nested transaction and simply reuse the other transaction. However, a ActiveRecord::Rollback within the nested transaction will be caught by the block of the nested transaction. Therefore it will be ignored by the outer transaction, and not cause a roll back!
To avoid this unexpected ...

Linked content

Workflow: How to use a key management service to encrypt passwords in the database

This is an extract from the linked article. It shows an approach on how to implement encrypted passwords with the AWS Key Management Service (KMS).

For most applications it's enough to use a hashed password with a salt (e.g. the gem devise defaults to this).

Upon password creation

  1. Generate hash as hash of password + salt.

  2. Encrypt the hash with a public key from KMS (you can store the public key in your server code).

  3. In your database sto...

Carrierwave: How to migrate to another folder structure

A flat folder structure can be cool if you have only a few folders but can be painful for huge amounts. We recently had this issue in a project with more than 100.000 attachments, where we used a structure like this /attachments/123456789/file.pdf.

Even the ls command lasted several minutes to show us the content of the attachments folder.

So we decided to use a more hierarchical structure with a limited maximum of folder per layer. As our attachment folder will grow very fast we choosed to use three layers, but that's up to you. Here...

Fixing AfterAll TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'

This error occurs when passing an object instead of a string to Jasmine's describe():

# Bad
describe(HoverClass, function() { ... })

# Correct
describe('HoverClass', function() { ... })

RubyMine: Restore main menu in Ubuntu

After a recent Ubuntu update I didn't see the main menu bar of the RubyMine IDE (File | Edit | View | ...) anymore.

This could be solved by changing a RubyMine registry entry:

  • Search "registry" within the "Actions" search
    • press ctrl + alt + n > click on Actions > type registry > click on Registry...
  • Scroll down to linux.native.menu and disable the checkbox

After rebooting RubyMine, you'll have gotten the menu bar back.

Repeats

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.

Repeats

How does Sentry group exceptions?

When you use Sentry to monitor exceptions, an important feature is Sentry's error grouping mechanism. This 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 that was active when you created the proj...

Linked content

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...

Repeats

Preloaded associations are filtered by conditions on the same table

When you eagerly load an association list using the :include option, and at the same time have a :condition on an included table, two things happen:

  1. Rails 2, 3, 4, 5 tries to load all involved records in a huge single query spanning multiple database tables.
  2. The preloaded association list is filtered by the :condition, even though you only wanted to use the :condition to filter the containing model.

The second case's behavior is mostly unexpected, because pre-loaded associations usually don't care about the circumstances unde...

Repeats

Selenium: How to debug the communication with the Webdriver API

Selenium allows you to log all requests to the Webdriver API. Therefore add the following line to e.g. features/support/selenium.rb:

Selenium::WebDriver.logger.level = :debug

If you want to see the output of the driver itself, here is an example on how to enable Chromedriver logging.

Example output

When you run a command like bundle exec cucumber --format=pretty features/some.feature you will see the API communication before the step is printed (here you see the log for the step And I press "Save").

...

Ruby: Appending lines to a file in sync

When writing some logs to a file, that don't use Ruby's logger utility, it is often useful to sync them. So other process can read the output just in time.

Example with enabled sync

log_path = '/tmp/some_log.log'

log_file = File.open(log_path, 'a+')
log_file.sync = true

log_file.puts('Some log message')
File.read(log_path) #=> "Some log message\n"

log_file.puts('Some other message')
File.read(log_path) #=> "Some log message\nSome other message\n"

Example ...

Repeats

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...

Useful Ruby Pathname method

If you have a Ruby Pathname, you can use the method :/ to append filepaths to it.

With this method, Ruby code can look like this:

Rails.root/"features"/"fixtures"/"picture.jpg"

Alternatively you can use the #join method, which feels less magic:

Rails.root.join('features', 'fixtures', 'picture.jpg')
This website uses short-lived cookies to improve usability.
Accept or learn more