Rbenv: Alias a Ruby version
For newer Ubuntu versions we currently need to install the patch level version 1.8.7-p375, otherwise the dev dependencies from openssl
will cause the installation to fail.
For a project that specifies the Ruby version 1.8.7
in the .ruby-version
the rbenv autoswitch will not work. You have several options how you can solve this problem:
- Install rbenv-aliases, which will alias your Ruby 1.8.7-p375 ...
Bundler: How to release a gem with 2FA enabled
Rubygems supports a 2FA for your account. Once enabled you need to provide your personal OTP code for every release. Despite the CLI of the rake release
task does not work well with the command prompt for your OTP code with Bundler versions < 2.0.2
. It just looks like the task is frozen:
- Workaround 1: Just type your OTP code and hit enter, your gem is released afterwards.
- Workaround 2: Upgrade to Bundler >=
2.0.2.
. Your supported Ruby versions for this gem must be>= 2.3
.
When r...
ActiveSupport includes Timecop-like helpers
ActiveSupport (since 4.1) includes test helpers to manipulate time, just like the Timecop gem:
-
To freeze the current time, use
freeze_time
(ActiveSupport 5.2+):freeze_time
-
To travel to a specific moment in time, use
travel_to
:travel_to 1.hour.from_now
Important
When freezing time with
#travel_to
, time will be frozen (like withfreeze_time
). This means that your application can't detect passage of time by usingTime.now
. -
To travel a re...
Ruby: The YAML safe_load method hides some pitfalls
The Ruby standard lib ships with a YAML Parser called Psych. But serializing and deserializing data seems not as obvious as if you are using JSON.
To safely write and read YAML files you should use Psych#dump
(String#to_yaml
) and Psych.safe_load
(YAML.safe_load
):
data = {'key' => 'value'}.to_yaml
=> "---\nkey: value\n"
YAML.safe_load(data)
=> {"key"=>"value"}
Unfortunately you might encounter a few pitfalls which are not obvious in the first place. All of them are a side effect that you can not configure Psych#dump
to o...
Capybara: Execute asynchronous JavaScript
Capybara provides execute_script
and evaluate_script
to execute JavaScript code in a Selenium-controlled browser. This however is not a good solution for asynchronous JavaScript.
Enter evaluate_async_script
, which allows you to execute some asynchronous code and wait until it finishes. There is a timeout of a couple of seconds, so it will not wait forever.
Use it like this:
page.evaluate_async_script(<<~JS)
let [done] = arguments
doSomethingAsynchronous().then(() => {
done() // call this to indicate we're done
})
J...
Email validation regex
There is a practical short list for valid/invalid example email addresses - Thanks to Florian L.! The definition for valid emails (RFC 5322) can be unhandy for some reasons, though.
Since Ruby 2.3, Ruby's URI lib provides a built-in email regex URI::MailTo::EMAIL_REGEXP
. That's the best solution to work with.
/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[...
Integrating or upgrading makandra-rubocop
Introduction
Most of the time it is a tedious task to apply a code style guide to an existing code base as there are likely to be a lot of conflicts. At makandra we are using makandra-rubocop to have code style checks. Here is some advice on how to add makandra-rubocop efficiently.
Note
RubyMine by default has a Rubocop inspection with rules that we don't always agree with. We recommend replacing this with makandra-rubocop or disabling the inspection.
...
Fix error: rails console No such file to load -- irb/encoding_aliases.rb (LoadError)
I got this error after upgrading Ruby from 2.4.5 to 2.6.4 when I opened the Rails console - rails server
still worked.
Running via Spring preloader in process 14679
Loading development environment (Rails 5.2.2.1)
Traceback (most recent call last):
.../lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/application.rb:175:in 'fork': No such file to load -- irb/encoding_aliases.rb (LoadError)
.../lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/application.rb:175:in 'fork': undefined method 'reject!' for nil:NilClass (NoMethodError)
.../li...
How to enable Chromedriver logging
When using Chrome for Selenium tests, the chromedriver
binary will be used to control Chrome. To debug problems that stem from Selenium's Chrome and/or Chromedriver, you might want to enable logging for the chromedriver itself. Here is how.
Option 1: Use Selenium::WebDriver::Service
In your test setup, you may already have something like Capybara::Selenium::Driver.new(@app, browser: :chrome, options: ...)
, especially when passing options like device emulation.
Similar to options
, simply add an extra key service
and pass an inst...
palkan/isolator: Detect non-atomic interactions within DB transactions
With this gem your transaction
blocks raise an error when they have side effects that cannot be rolled back.
By default it checks whether you're connecting with HTTP, queuing a Sidekiq job or sending an e-mail within a transaction
. You can add custom checks, too.
Found in this RubyGuides article.
Convert SCSS to SASS
The ruby sass gem also installs a command line tool to convert to and from SCSS. Use it for a directory of .scss
-files like
sass-convert -R assets/stylesheets --from scss --to sass
Rails: Do not load frameworks you don't need
Rails is split into a large number of (sub-) frameworks.
The most important and central of those are
- activesupport (extends the Ruby standard library)
- activerecord / activemodel (ORM for Rails)
- actionview / actionpack (controller / views)
- actionmailer (sends mails)
However, there are also some more situational frameworks included, such as
- actioncable (real time communications using websockets)
- actionmailbox (receives mails)
- actiontext (support for WYSIWYG text editor)
- activejob (background jobs)
- activestorage (file uplo...
Take care of existing users when upgrading Clearance
When upgrading Clearance, pay attention whether the password hashing strategy might have changed. Old clearance versions (< 1.0) used SHA1-encrypted passwords by default. Current versions default to BCrypt.
If you simply upgrade without taking this into account, users will get a BCrypt::Errors::InvalidHash
when trying to sign in. Your tests will not notice this, since they create new users for each scenario.
To fix it, you'll either have to force all users to reset their passwords, or you can allow old users to keep signing in with t...
Ruby: How to use global variables for a conditional debugger
You can share a state in Ruby with global variables. Even if you should avoid them whenever possible, for debugging an application this could be temporary quite handy.
Example:
class User
after_save { byebug if $debug; nil }
def lock
self.locked = true
save
end
end
Rspec.describe User do
let(:user) { create(:user) }
before do
# Many users are created and saved in this hook, but we don't want the debugger to stop for them...
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...
Webpack(er): A primer
webpack is a very powerful asset bundler written in node.js to bundle (ES6) JavaScript modules, stylesheets, images, and other assets for consumption in browsers.
Webpacker is a wrapper around webpack that handles integration with Rails.
This is a short introduction.
Installation
If you haven't already, you need to install node.js and Yarn.
Then, put
gem 'webpacker', '~> 4.x' # check if 4.x is still cu...
Installing Ruby 2.3 or below on Ubuntu 17 and above
From Ubuntu 17, rbenv fails to install Ruby below 2.4 because of a mismatching OpenSSL dependency: it needs libssl1.0-dev
for the installation process, but recent Ubuntus come with libssl-dev
.
From the linked StackOverflow comment:
As far as I know (and tested), Ruby versions < 2.4 requires libssl1.0, while >2.4 libssl1.1+. The two libssl packages conflict with each other, so you can't have both of them, so I had to juggle the libs in order to install the required ruby version. To make things even funnier (or more complicated),...
RubyMine: Efficiently filtering results in the "Finder" overlay
RubyMine comes with a nice way to grep through your project's files: The finder (ctrl + shift + f
). Don't be discouraged about the notice 100+ matches in n+ files
if your searched keyword is too general or widely used in your project.
RubyMine comes with a few ways to narrow down the resulting list, don't hesitate to apply those filters to speed up your search. Your keybinding might vary based on your personal settings.
File mask (alt + k
)
If you already know the file extension of your ...
How to make RubyMine aware of Cucumber steps defined in gems
If your Ruby project includes a gem like Spreewald that comes with some external step definition, RubyMine does not know about them by default and will highlight the step as an undefined reference:
To link these external step definitions to RubyMine, add the corresponding gems to your RubyMine-Settings:
- Go to Settings (
ctrl + alt + s
) - Go to Languages and Frameworks
- Go to Cucumber
- There, add your gem (e.g "spreewald") via the little "+" from the b...
How to get a backtrace if rspec (or any other ruby process) hangs with no output
If rspec hangs with no output and you dont get a backtrace neither with --backtrace
nor by just killing it with crtl-c,
you can put the following in your spec/spec_helper.rb
:
puts "rspec pid: #{Process.pid}"
trap 'USR1' do
threads = Thread.list
puts
puts "=" * 80
puts "Received USR1 signal; printing all #{threads.count} thread backtraces."
threads.each do |thr|
description = thr == Thread.main ? "Main thread" : thr.inspect
puts
puts "#{description} backtrace: "
puts thr.backtrace.join("\n")
end
...
Unpoly: Testing values for presence or blankness
In Ruby on Rails, all objects have a useful blank?
method. It returns true for nil
but also for empty strings or empty arrays. There is also a universal method present?
which returns true
for all values that are not blank?
.
In JavaScript you need to roll your own implementation of blank?
and present?
.
If your application uses [Unpoly](...
How to: Fix json 1.8.3 with Ruby 2.5
The gem json
fails to install for Ruby 2.5 if you use a version equal or below 1.8.3
.
Run bundle update json --conservative
to solve this issue.
The backtrace you will encounter looks like this:
Building native extensions. This could take a while...
ERROR: Error installing json:
ERROR: Failed to build gem native extension.
current directory: /home/user/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/json-1.8.3/ext/json/ext/generator
/home/user/.rbenv/versions/2.5.3/bin/ruby -I /home/user/.rbenv/versions/2.5.3/lib/ruby/si...
Bundler: How to install version 1 instead of 2 (latest version)
When installing a gem you can use version comparators like >=
or ~>
. That way it is possible to fetch the latest version of Bundler 1 with this command:
gem install bundler -v '~>1'
How to install bundler for Ruby < 2.3 is a common usecase where you might need Bundler 1.
cucumber_factory: How to keep using Cucumber 2 Transforms in Cucumber 3
Cucumber up to version 2 had a neat feature called Step Argument Transforms which was dropped in favor of Cucumber 3 ParameterTypes. While I strongly encourage you to drop your legacy Transforms when upgrading to Cucumber 3, it might not always be possible due to their different design.
This is a guide on how to keep the exact same functionality of your old Transforms
while writing them in the style of new `Paramet...