Ruby and Rails have several methods for creating a new object that looks like another: clone
, dup
, deep_dup
. When using them you should be aware of their differences so that you can select the method you really need.
clone
frozen
, tainted
and modules that the object has been extended withYou can install rubygems 3.0.8
(released on February 18, 2020) to keep all the Gem::Specification#rubyforge_project
deprecation warnings away from your development log. With Rubygems >= 3.1
this deprecation warning was introduced. While maintaining older projects this could get quite annoying and the fix below might okey, for newer projects the right ways is to upgrade the gems.
gem update --system 3.0.8
Example message:
NOTE: Gem::Specification#rubyforge_project= is deprecated with no replacement. It will be removed o...
You can run bundle install in parallel. This might be helpful for development, where you often install many new gems when switching between projects.
lscpu
~/.bundle/config
globally (replace 8
with your number of proccessors):bundle config jobs 8
Note
If you suspect parallel execution for bundling issues, you can try serially with
bundle install --jobs 1
.
When you have many changes, and you want to spread them across different commits, here is a way to stage all changes matching a given regular expression for a single commit.
Consider the following git diff
output.
diff --git a/file1.rb b/file1.rb
index 806ca88..36d536b 100644
--- a/file1.rb
+++ b/file1.rb
@@ -1,7 +1,5 @@
-# Here is a useless comment.
-# It will be removed.
class File1
- def foo
+ def bar
# ...
end
end
diff --git a/file2.rb b/file2.rb
index 550e1c6..600f4e3 100644
--- a/file2.rb
+++ b/file2...
The linked GitHub repository is a bit like our "dev" cards deck, but groomed from a single person (Josh Branchaud). It includes an extensive list of over 900 TILs on many topics that might be interesting for most of us. (e.g. Ruby, Rails, Git, Unix..)
Here is an excerpt of all the Ruby TILs that were new to me. I encourage you to take your time to skim over the original list as well!
With puma
you can have concurrent requests. There are two concepts on how Puma can handle two incoming requests: Workers and Threads.
Puma can have multiple workers. Each worker is a process fork from puma and therefore a very heavy instance and can have multiple threads, that handle the incoming requests.
Example: A Puma server with 2 workers
and 1 thread
each can handle 2 request in parallel
. A third request has to wait until the thread of one of the workers is free.
Rails is thread-safe since version 4 (n...
Simplecov is a code coverage tool. This helps you to find out which parts of your application are not tested.
Integrating this in a rails project with rspec, cucumber and parallel_tests is easy.
Add it to your Gemfile and bundle
group :test do
gem 'simplecov', require: false
end
Add a .simplecov
file in your project root:
SimpleCov.start 'rails' do
# any custom configs like groups and filters can be here at a central place
enable_cov...
"Everything in Ruby is an object". This is also true for nested hashes and arrays. If you copy a hash with #clone
or #dup
and you modify the copy, you will run into the following behavior:
original_hash = { foo: { bar: 'original value' } }
copied_hash = original_hash.dup
copied_hash[:foo][:bar] = 'changed value'
original_hash # => { foo: { bar: "changed value" }
This is, because { bar: 'baz' }
is an object, which is referenced in :foo
. The copy of original_hash
still holds the reference to the same object, so alterin...
A recent patch level Ruby update caused troubles to some of us as applications started to complain about incompatible gem versions. I'll try to explain how the faulty state most likely is achieved and how to fix it.
When you deploy a new Ruby version with capistrano-opscomplete, it will take care of a few things:
Embedding videos on a website is very easy, add a <video>
tag to your source code and it just works. Most of the time.
The thing is: Both the operating system and Browser of your client must support the container and codecs of your video. To ensure playback on every device, you have to transcode your videos to one or more versions of which they are supported by every device out there.
In this card, I'll explore the available audio and video standards we have right now. The goal is to built a pipeline that...
Ruby's Net::HTTP library repeats a failing request once, as long as it deems it idempotent (GET, HEAD etc). Both requests will use the configured timeout. Hence, if both requests time out, Net::HTTP will only return after twice the configured timeout.
This can become an issue if you rely on the timeout to strike precisely.
TLS/SSL certificates are often used for HTTPS traffic. Occasionally a service may also use their TLS certificate to support public-key encrypting data (e.g. when it is part of the URI and visible to the user, but contains sensitive information).
Here is how to easily fetch such certificate data.
certificate = Net::HTTP.start('example.com', 443, use_ssl: true) { |http| http.peer_cert }
# => #<OpenSSL::X509::Certificate: subject=#<OpenSSL::X509::Name CN=www.example.org,...>
certificate.public_key
# => #<OpenSSL::PKey::RSA:0x...
The linked article has a great explanation how to to deal with string encodings in Ruby. Furthermore you can check out some of our cards about encoding:
Root Insurance runs their application as a monolithic Rails application – but they've modularized it inside its repository. Here is their approach in summary:
When you have two inputs, where one contains the name of the other (eg. Name
and Name with special treatment
), Capybara's fill_in
method will fail with the following message:
Ambiguous match, found 2 elements matching visible field "Name" that is not disabled (Capybara::Ambiguous)
You can force Capybara to match exactly what you are typing (which makes your tests better anyways) with match: :prefer_exact
:
name = 'Name'
value = 'Bettertest Cucumberbatch'
fill_in(field, with: value, match: :prefer_exact)
Furthermore...
Debugging image color profiles is hard. You can't trust your eyes in this matter, as the image rendering depends on multiple factors. At least the operation system, browser or image viewer software and monitor influence the resulting image colors on your screen.
When we offer our users the possibility to upload images, they will most likely contain tons of EXIF metadata and sometimes exotic color profiles like eciRGB. We want to get rid of the metadata, as it might contain sensitiv...
If you want to make your Rails application be capable of sending SMTP emails, check out the action mailer configuration section in the Ruby on Rails guide.
TL;DR you will end up having an smtp_settings
hash that looks something like this:
smtp_settings = {
address: ...,
domain: ...,
port: ...,
user_name: ...,
password: ...,
authentication: ...,
tls: ...,
enable_starttls_auto: ...,
}
This hash can be set as the `delivery_me...
It's every developer's nightmare: SQL queries that get large and unwieldy. This can happen fairly quickly with the addition of multiple joins, a subquery and some complicated filtering logic. I have personally seen queries grow to nearly one hundred lines long in both the financial services and health industries.
Luckily Postgres provides two ways to encapsulate large queries: Views and Materialized Views. In this article, we will cover in detail how to utilize both views and materialized views within Ruby on Rails, and we can even take...
Install the latest bundler
version:
gem install bundler
Fetching bundler-2.3.5.gem
Successfully installed bundler-2.3.5
1 gem installed
Update the bundler version in Gemfile.lock
:
bundle update --bundler
Confirm it worked:
$ tail -n2 Gemfile.lock
BUNDLED WITH
2.3.5
Bundler should automatically detect the latest installed version. If it does not, you can specify your preferred version like so:
b...
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:
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:
2.0.2.
. Your supported Ruby versions for this gem must be >= 2.3
.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 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...
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](?:[...