Call original method when monkey patching
Ruby offers monkey patching methods in order to change the behavior of a library if there's no better way.
We can call the method we're overriding inside our monkey patch:
class Foo
def bar(argument)
'Hello' + argument
end
end
module FooExtensions
def bar
super(' in my') + ' World'
end
end
class Foo
prepend FooExtensions # the only change to above: prepend instead of include
end
Foo.new.bar # => 'Hello in my...
Ruby: How to keep split delimiter (separate, or as part of substrings)
Ruby's String#split returns an array of substrings from the given string. Usually, this is missing the split characters:
>> 'user@example.com'.split('@')
=> ["user", "example.com"]
If you want to join those parts later on, you might know the split character and can just use it to join explicitly.
But if you split by a regular expression (for a set of split characters) that information is lost:
>> 'user@example.com'.split(/[@\.]/)
=> ["user", "example", "com"]
You can use a capture group to make those characters ...
SSHKit 1.9.0 failure for Capistrano deploy
SSHKit 1.9.0 might fail with the following error, when trying to deploy a Rail application. Upgrading the gem to version 1.21.0 fixed the issue.
Traceback (most recent call last):
17: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9.0/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
16: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9.0/lib/sshkit/backends/abstract.rb:29:in `run'
15: from /home/user/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/sshkit-1.9....
Missing certificates for rubygems and bundler in Ruby 1.8.7
Using Ruby 1.8.7 you will not be able to use the maximum versions Rubygems 1.8.30 and Bundler 1.17.3 with https://rubygems.org/ anymore. This is a result of a server certificate on December 5th, 2020. The resulting errors will look like following:
TypeError: can't modify frozen objectCould not verify the SSL certificate for https://rubygems.org/*Bundler::Fetcher::CertificateFailureError: Could not verify the SSL certificate for https://index.rubygems.org/versions.- `Error fetching data: hostname was not m...
Configuring Webpacker deployments with Capistrano
When deploying a Rails application that is using Webpacker and Capistrano, there are a few configuration tweaks that optimize the experience.
Using capistrano-rails
capistrano-rails is a Gem that adds Rails specifics to Capistrano, i.e. support for Bundler, assets, and migrations. While it is designed for Asset Pipeline (Sprockets) assets, it can easily be configured for Webpacker. This brings these features to the Webpacker world:
- Automatic removal of expired assets
- Manifest backups
How to fix: Pasting in IRB 1.2+ is very slow
IRB 1.2 (shipped with Ruby 2.7, but works on 2.5+) brings pretty syntax highlighting and multiline cursor navigation. However, pasting longer contents is incredibly slow. You can fix that by disabling said features. [1]
Ruby 3.0.0-pre2 solved the issue (however, the fix does not appear to be included in IRB 1.2.6, it must be Ruby itself).
Option 1:
Add a command line flag when opening an IRB:
irb --nomultiline
This also works on modern Rails...
Rails developers: Have better context in Git diffs
Git diffs show the surrounding contexts for diff hunks. It does so by applying regular expressions to find the beginning of a context. When it comes to Ruby, however, it will not find method heads and travel up to the class definition:
@@ -24,7 +24,7 @@ class TicketPdf # <=== Actually expected here: the method definition
ApplicationController.render(
"tickets/index.html.haml",
layout: "tickets",
- assigns: { tickets: tickets }
+ assigns: { tickets: tickets, event_name: event_name }
)
end
end
```...
Show/Hide Rubocop marking in RubyMine
If you have installed Rubocop in your project, RubyMine can show you Rubocop violations immediately in your editor. You probably already know this feature.
Example
Enable/Disable marking
If your RubyMine does not show you any violations, although there are some, you may have to enable the setting first.
To do so, open Navigate -> Search Everywhere -> Actions (Or use the shortcut CTRL + SHIFT + A) and type in "rubocop", then you should see some...
Convert curl commands to ruby code
curl-to-ruby is a handy tool that converts your curl command to ruby code that uses the Net::HTTP library.
Example
curl -X POST -d
"grant_type=password&email=email&password=password"
localhost:3000/oauth/token
will output to:
require 'net/http'
require 'uri'
uri = URI.parse("http://localhost:3000/oauth/token")
request = Net::HTTP::Post.new(uri)
request.set_form_data(
"email" => "email",
"grant_type" => "password",
"password" => "password",
)
req_options =...
Ruby: Comparing a string or regex with another string
In Rubocop you might notice the cop Style/CaseEquality for e.g. this example:
def foo(expected, actual)
expected === actual
end
In case expected is a Regex, it suggests to change it to the following pattern:
def foo(expected, actual)
expected.match?(actual)
end
In case expected is a Regex or a String, you need to keep ===. Otherwise the actual expression is always converted to a regular expression.
# For expected === actual
foo('Test(s)', 'Test(s)') #=> true
# For expected.match?(actual)
foo('Test(...
Ruby: A short summary of available hooks in Cucumber
Here is a short summary of Cucumber hooks in Ruby taken from https://github.com/cucumber/cucumber-ruby. Note that the BeforeStep is currently not existing in the Ruby implementation of Cucumber.
Before hooks run before the first step of each scenario.
Before do |scenario|
...
end
After hooks run after the last step of each scenario, even when the step result is failed, undefined, pending or skipped.
...
Migrate gem tests from Travis CI to Github Actions with gemika
We currently test most of our gems on Travis CI, but want to migrate those tests to Github Actions. This is a step-by-step guide on how to do this.
Note that this guide requires the gem to use gemika.
- Go to a new "ci" branch:
git checkout -b ci - Update gemika to version >= 0.5.0 in all your Gemfiles.
- Have gemika generate a Github Actions workflow definition by running
mkdir -p .github/workflows; bundle exec rake gemika:generate_github_actions_workflow > .github/workf...
Installing old versions of mysql2 on Ubuntu 20.04+
On some of our older projects, we use the mysql2 gem. Unfortunately, versions 0.2.x (required for Rails 2.3) and versions 0.3.x (required for Rails 3.2) can no longer be installed on Ubuntu 20.04. Trying this either leads to errors when compiling the native extension, or a segfaults when using it.
For Rails 4.2, mysql2 version 0.4.10 seems to work okay. If you still have issues, upgrade to 0.5.x, which should be compatible.
To install it, you have to switch the mysql2 gem to our fork. In your Gemfile, ...
Installing Ruby <= 2.3 on Ubuntu 20.04+
Installing old Rubies (<= 2.3) with a standard rbenv + ruby-build is no longer possible on Ubuntu 20.04. This is because those Rubies depend on OpenSSL 1.0 which is no longer shipped with current Ubuntus.
We have forked ruby-build with a workaround that makes it compile and statically link the latest OpenSSL 1.0 version. This works on Ubuntu 20.04, as well as on Ubuntu 18.04.
To switch to our fork of ruby-build, update ruby-build like this
git -C ~/.rbenv/plugins/ruby-build remote add makandra...
How to implement simple queue limiting/throttling for Sidekiq
The sidekiq-rate-limiter gem allows rate-limiting Sidekiq jobs and works like a charm. However, it needs to be integrated on a per-worker basis.
If you want to limit a whole queue instead, and if your requirements are simple enough, you can do it via a Sidekiq middleware yourself.
Here is an example that limits concurrency of the "mailers" queue to 1. It uses a database mutex via the [with_advisory_lock](https://github.com/ClosureTree/wit...
VCR and the webdrivers gem
If you're using the webdrivers gem and VCR together, depending on your configuration, VCR will yell at you regulary.
The webdrivers gem tries to update your webdrivers on your local machine. To do so, it checks the internet for newer versions, firing an HTTP-request to e.g. https://chromedriver.storage.googleapis.com
You can "fix" this in multiple ways:
-
Update your drivers on your machine with
RAILS_ENV=test rake webdrivers:chromedriver:update -
Ignore the driver update-URL in your ...
Pagy
Pagy is a gem for pagination.
They make some bold claims:
Pagy is the ultimate pagination gem that outperforms the others in each and every benchmark and comparison.
Maybe this is worth trying out.
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...
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
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.
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
-
Generate hash as hash of password + salt.
-
Encrypt the hash with a public key from KMS (you can store the public key in your server code).
-
In your database sto...
How to fix: Rails query logs always show lib/active_record/log_subscriber.rb as source
Rails 5.2+ supports "verbose query logs" where it shows the source of a query in the application log.
Normally, it looks like this:
User Load (0.5ms) SELECT "users".* FROM "users" WHERE ...
↳ app/controllers/users_controller.rb:42:in `load_users'
However, you may encounter ActiveRecord's LogSubscriber as the source for all/most queries which is not helpful at all:
User Load (0.5ms) SELECT "users".* FROM "users" WHERE ...
↳ activerecord (6.0.3.3) lib/active_record/log_subscriber.rb:100:in `debug'
While th...
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...