Using the Ruby block shortcut with arguments
Ruby has this handy block shortcut map(&:to_i)
for map { |x| x.to_i }
. However, it is limited to argument-less method invocations.
To call a method with an argument, you usually need to use the full block form. A common and annoying case is retrieving values from a list of hashes (imagine using a JSON API):
users = [ { name: 'Dominik', color: 'blue' }, { name: 'Stefan', color: 'red'} ]
names = users.collect do |user|
user[:name]
end
If you're using Rails 5+, this example is covered by Enumerable#pluck
(`users.pluck(:name)...
Whenever: Don't forget leading zeros for hours!
Whenever is a Ruby gem that provides a nicer syntax for writing and deploying cron jobs.
Leading zeros are important for whenever if you use the 24-hours format!
This schedule.rb
:
every 1.day, at: '3:00', roles: [:primary_cron] do
runner 'Scheduler.delay.do_things'
end
will lead to this crontab entry (crontab -l
) with the default configuration:
0 15 * * * /bin/bash -l -c 'cd /var/www/my-project/releases/20180607182518 && bin/rails runner -e production '\''Scheduler.delay.do_things'\'''
Which would run on 3...
Ruby: All Errno::ERROR constants inherit from SystemCallError
To catch all possible exceptions from a network call, we need to rescue
many error classes like this:
rescue SocketError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ECONNABORTED, Errno::EHOSTUNREACH, OpenSSL::SSL::SSLError, MyHttpLib::BadResponse
You can shorten this a bit by rescuing SystemCallError
, which is a base class for all Errno::
exceptions:
rescue SocketError, SystemCallError, OpenSSL::SSL::SSLError, MyHttpLib::BadResponse
Some high-level ...
ActiveRecord::Store: migrate data in store
When you need to store structured data (like Ruby hashes) in a single database column with ActiveRecord, a simple way is to use PostgreSQL's jsonb
columns. ActiveRecord will automatically serialize and deserialize your Hash to and from JSON, and you can index JSON paths for fast reads.
As an alternative, ActiveRecord::Store
offers a way to store hashes in a single database column. This card will show you how to migrate those hashes in an ActiveRecord::Migration
by example:
...
Capistrano + Rails: Tagging production deploys
Just like Ruby Gems tag their version releases to the corresponding Git commit, it can be helpful to track production deploys within the commit history. This task does the tagging for you.
Capistrano 3
# lib/capistrano/tasks/deploy.rb
namespace :deploy do
...
desc 'Tag the deployed revision'
task :tag_revision do
date = Date.today.to_s
puts `git tag deploy-#{date} #{fetch :current_revision}`
puts `git push --tags origin`
end
end
# config/deploy/production.rb
after 'deploy:finished', 'deploy:tag_...
Bundler error: Downloading gem revealed dependencies not in the API
Recent Bundler (1.16.1) started complaining about missing dependencies in the Gemfile. This is due to a stricter handling of specifications (see attached link).
The error message looks like this:
Downloading example-gem-1.2.3 revealed dependencies not in the API or the lockfile (other-gem (< 3)).
Either installing with `--full-index` or running `bundle update example-gem` should fix the problem.
However, bundle install --full-index
did not any better for me, and bundle update
is not always a viable solution.
Easiest solut...
Fixing: Gem::Package::PathError: installing into parent path is not allowed
This might be a known issue with Rubygems 2.5.1. This will help:
gem update --system
Generating test images on the fly via JavaScript or Ruby
When you need test images, instead of using services like lorempixel or placehold.it you may generate test images yourself.
Here we build a simple SVG image and wrap it into a data:
URI. All browsers support SVG, and you can easily adjust it yourself.
Simply set it as an image's src
attribute.
JavaScript
Simple solution in modern JavaScript, e.g. for use in the client's browser:
function svgUri(text) {
let svg = `
<svg wid...
RubyMine: You can disable inspections you don't care about
When you find yourself constantly ignoring a RubyMine warning, you can simple disable that warning and de-clutter your editor. E.g. in my Cucumber scenarios RubyMine underlines 90% of all lines because it does not know about spreewald, making the file really hard to read.
You can disable any unwanted inspection by opening File / Settings / Editor / Inspections
and searching for the warning text.
What you disable or keep is up to your personal preference. I personally disable at least the following...
Running Rails 2 apps with modern MariaDB SQL server
You might have some trouble running a Rails LTS 2 app with MySQL 5.7.
If you don't want to hack Mysql 5.6 into your modern Ubuntu or use the MySQL sandbox, you might want to try MariaDB 10.x.
MariaDB 10.x should work with both old and new Rails applications.
[Switch to MariaDB](https://makandracards.com/makandra/468343-how-...
Making httpclient use the operating system's SSL cert store
The httpclient gem comes with a custom SSL cert store.
While an customizable, application-level cert store is great when you need to deal with broken or self-signed certificates, you usually want to use the cert store from the underlying Linux. The Linux cert store is updated periodically while httpclient's cert store goes out of date and will eventually not be able to verify certs.
To use the cert store from the underlying operating system:
client = HTTPClient.new
client.ssl_config.cert_store...
Upgrading a Rails app to Cucumber 3
Upgrade gems
You need to update a lof gems. Make sure you don't have any version constraints in your Gemfile
or your bundle update
won't do anything!
Upgrade cucumber_priority
:
bundle update cucumber_priority
Upgrade spreewald
:
bundle update spreewald
Upgrade cucumber_factory
:
bundle update cucumber_factory
Upgrade parallel_tests
:
bundle update parallel_tests
Even on the latest version, parallel_tests
will print some deprecation warnings due to using an older formatter A...
PostgreSQL: Upgrading your user to a superuser
Your default postgres user is named like your linux user. That default user has limited access privileges, which can cause issues such as:
- DatabaseCleaner needs to disable foreign key constraints before it can wipe the database.
- Importing a remote dump with geordi
- Asking Postgres to show the storage path of a database
Doing these things without a superuser will show a Postgres error or (in Ruby) raise PG::InsufficientPrivilege
.
To do so, the application's PostgreSQL user must be a superuser. ...
How to: Fix incorrect MySQL client library version
Bundler::GemRequireError: There was an error while trying to load the gem 'mysql2'.
Gem Load Error is: Incorrect MySQL client library version! This gem was compiled for 5.5.46 but the client library is 5.6.30.
Same as in Fix "libmysqlclient.so.20: cannot open shared object file: No such file or directory":
gem pristine mysql2
gem pristine
re-installs a gem (without re-downloading), re-compiling all native extensions in the process.
Mysql::Error: BLOB/TEXT column can't have a default value
mysql> SELECT @@global.version;
+------------------+
| @@global.version |
+------------------+
| 5.6.30 |
+------------------+
1 row in set (0,00 sec)
MySQL 5.6 Reference Manual says "BLOB and TEXT columns cannot have DEFAULT values"
.
If you want to run migrations in development
here are two variants which might help. If you are not sure about the side effects (e.g. your application is broken when it doesn't set additional default values on application side, too...
How to: Solve gem loaded specs mutex
Use bundler > 1.15
to fix Gem::LOADED_SPECS_MUTEX (NameError)
.
Given the following project:
ruby -v
ruby 1.8.7
bundler -v
Bundler version 1.13.7
gem -v
1.8.30
rails -v
Rails 3.2.22.1
Running specs or features resulted in:
uninitialized constant Gem::LOADED_SPECS_MUTEX (NameError)
The previous settings described in Maximum version of Rubygems and Bundler for Ruby 1.8.7 and Rails 2.3 (even the rails version was rails 3.2 and not 2.3) seems not to work here, so I used (also described in the ca...
ss: How to show listening ports
Note
netstat has mostly been superseeded by its more modern rewrite
ss
which nowadays comes pre-installed rather than netstat.
The most common options (especially all that are mentioned in this card) work the same way as they did with netstat
Sometimes it's necessary for you to check which ports are in use on your local machine and which process is using it. To list this information you can use the following command (which is pretty easy to memorize for Germans 🌷):
sudo ss -tulpn
-
t
: tcp -
u
: udp -
l
: listening p...
Configuring RubyGems to not install documentation by default
When installing gems, a lot of time is spent building locally installed documentation that you probably never use.
We recommend you disable documentation generation for gem install
by default.
Note that Bundler won't install documentation, so this advice applies only when installing gems manually.
If you don't already have it, create a ~/.gemrc
file. The gemrc is a Yaml file, so add the following line to add default switches to the gem
command.
gem: --no-document
(If you do n...
Katapult 0.3.0 released
Katapult 0.3.0 brings Rails 5 and Ruby 2.5 support with a new design, plus a ton of smaller features, fixes and improvements.
Features
- Generating a Rails 5.1.4 app on Ruby 2.5.0
- Dropped asset pipeline in favor of Webpacker
- The generated application now has a sleek, simple design based on Bootstrap
- Employing Unpoly
- New application model DSL shortcut
crud
for "create a model and a web UI with crud actions" - The generated application model is now a transformable e...
Ruby: Using all? with empty collection
Enumerable#all? returns true
for an empty collection. This totally makes sense but you have to think about it when making assumptions on relations which might be empty.
[].all?(&:will_never_be_called_here) => true
Example with empty collection
class Researcher < ActiveRecord::Base
has_many :papers
end
class Paper
validates :topic, inclusion: { in: ['computer_science', 'mathematics', 'economy'] }
end
Easy goal: Delete all researches who write onl...
Ruby: control flow with throw and catch
This article will show you how to use throw
and catch
. It's a nice tool to break out of multiple loops when a result is obtained.
Also see our card Ruby: A small summary of what return, break and next means for blocks.
Error during Rails 5 upgrade: Environment data not found in the schema
This error is raised because your old database does not have a configured environment yet, which Rails 5 enforces.
If this error occurs while migrating your parallel test databases, make sure to update the parallel_tests
gem first: current versions fix this. If you're still using Cucumber < v3, the latest version of parallel_tests
will be 2.18.0.
Writing a README for a project
Rails applications and ruby gems should have a README that gives the reader a quick overview of the project. Its size will vary as projects differ in complexity, but there should always be some introductory prose for a developer to read when starting on it.
Purpose
That's already the main purpose of a project README: Give a new developer a quick overview of the project. In sketching this outline, the README should notify the reader of any peculiarity he needs to know of.
Remember that in a few months, you'll be a kind of "new ...
xlsxtream: Streaming & Fast XLSX Spreadsheet Writer for Ruby
When writing XLSX files, there are gems like rubyXL or axlsx. While they do offer features like formatting or graphs, to represent spreadsheet cells, they have to keep several Ruby objects in memory. When writing huge files, both will become slow and consume lots of memory.
Enter Xlsxtream, a Ruby XLSX library with less features (e.g. no individual cell styles) but which does away with the memory issue by streaming ...