If you use transactional_fixtures
or the database_cleaner gem with strategy :transaction
, after_commit
callbacks will not be fired in your tests.
Rails 5 has a fix for this issue and no further action is needed.
Add the gem test_after_commit to your test
group in the Gemfile and you are done. You don't need to change the database strategy to deletion
(wh...
When you need to insert many records into the same table, performance may become an issue.
What you can do to save time is to open a transaction and save multiple records within that transaction:
transaction do
500.times { Model.create! }
end
Although you will still trigger 500 INSERT
statements, they will complete considerably faster.
When I tried it out with a simple model and 500 iterations, the loop completed in 1.5 seconds vs. 6 seconds without a transaction.
Another fast way to insert many ...
If you have a fully functional CI pipeline but no CD, you might find yourself frequently waiting for CI (with "merge after pipeline succeeds") just to perform the deployment.
The following command waits for the next commit that lands on the current branch (should be main
or similar) and proceeds to deploy staging afterwards:
alias await-deployment='watch -g git pull && bundle exec cap staging deploy'
Note
Use at your own risk.
You could be deploying code from someone else that was pushed to the same branch in the meantime.
Git commands like diff
use the less
binary for their output representation.
I often find myself searching for strings like todo
, then switching to the case-insensitive mode (-i
) and re-doing my search.
Today I figured out that you can configure git to show case insensitive diffs every time:
git config --global core.pager 'less -i'
Geordi will now suggest related commands and options (hand-picked). If a command has suggestions, a single suggestion is printed with a 10% probability after a successful command.
You can use rake --where task
to find the source location that defines task
:
bundle exec rake --where assets:precompile
rake assets:precompile /home/henning/.rbenv/versions/2.6.6/lib/ruby/gems/2.6.0/gems/precompiled_assets-0.2.1/lib/precompiled_assets/tasks/assets.rake:5:in `block in <main>'
Within Vim do the following:
ctrl + v
to enter select mode to select all characters in one columnshift + i
to got into "multiple" insert modeESC
-character exit insert modeESC
-character to apply all changesHint
This does not work with deleting and editing at once
- If you first want to delete the content, can also use the select mode ...
How you order elements in the <head> can have an effect on the (perceived) performance of the page.
This script helps you identify which elements are out of order.
Also available as a Chrome Extension. It shows the actual order of head elements, and suggests an optimal order for page performance.
By default, your terminal emulator (Gnome Terminal, Terminator, etc.) sets some kind of window title to reflect the shell type you are running (e.g. /bin/bash
).
This is most often not too helpful, but you can change that from your shell.
To set a specific title, print an escape sequence like this:
echo -en "\033]0;Hello\a"
You can easily include the current path:
echo -en "\033]0;$(pwd)\a"
Or, to replace your home directory's part with a tilde:
echo -en "\033]0;$(pwd | sed -e "s;^$HOME;~;")\a"
Or,...
Ruby has a set of methods to convert an object to another representation. Most of them come in explicit and implicit flavor.
explicit | implicit |
---|---|
to_a |
to_ary |
to_h |
to_hash |
to_s |
to_str |
to_i |
to_int |
There may be even more.
Don't name your methods like the implicit version (most prominently to_hash
) but the like the explicit one.
Explicit conversion happens when requesting it, e.g. with the splat opera...
In long diffs, it can become impossible to spot small changes in larger blocks of moved code. This may be either a method that was moved from the top to the bottom of a file, or a long test file that was split in many.
Fortunately, Git offers a special highlighting mode that directs the reader's attention to relevant code parts:
git diff --color-moved=dimmed-zebra
It will dim lines that were moved around without changes, and highlight changed lines.
To easily use dimmed-zebra mode, configure an alias:
# ~/.gitconfig
[alias]
...
When two classes implement the same behavior (methods, callbacks, etc.), you should extract that behavior into a trait or module. This card describes how to test that extracted behavior without repeating yourself.
Note that the examples below use Modularity traits to extract shared behavior. This is simply because we like to do it that way at makandra. The same techniques apply for modules and overriding self.included
.
Example
---...
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
.
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 netstat -tulpn
t
: tcpu
: udpl
: listening portsp
: processn
: networkUse sudo
to see the name of the process.
You should look for rows with State: LISTEN
.
Rows for local address 127.0.0.1
or...
A JavaScript error in an E2E test with Selenium will not cause your test to fail. This may cause you to miss errors in your frontend code.
Using the BrowserConsole
helper below you can check your browser's error console from your E2E tests.
The following will raise BrowserConsole::ErrorsPresent
if there is an error on the browser console:
BrowserConsole.assert_no_errors!
You can ignore errors by their exact message:
BrowserConsole.ignore('Browser is burning')
You can ignore errors with me...
As we are slowly switching from Cucumber scenarios to RSpec feature specs, you might be tempted to write assertions like this one:
feature 'authorization for cards management' do
let(:guest_user) { create(:user, :guest) }
scenario "rejects guest users from adding new cards", js: true do
sign_in guest_user
expect { visit new_cards_path }.to raise_error(Consul::Powerless)
end
end
While this might work under certain circumstances¹, there is a good chance you'll see two exceptions when running this single spec:
With this Ruby script you can print all values in a Redis database to your console (derived from this bash script).
Note: Do not run this command in production. This is for debugging purposes only.
def pretty_print_redis(redis)
redis.keys.each_with_object({}) do |key, hash|
type = redis.type(key)
hash[key] = case type
when 'string'
redis.get(key)
when 'hash'
redis.hgetall(key)
when 'list'
redis.lrange(key, 0, -1)
when 'set'
redis.smembers(...
Web forms can be made much more usable with a few HTML attributes. Short summary:
Even though you can get 90% of debugging done with up to 5 basic byebug
commands, it comes in handy with it's features for many use cases beyond that to make your life easier.
For this cheatsheat I tried to structure the most useful commands by different use cases, such that a practical oriented overview of all the commands can be gathered by going over this cheatsheet. For some commands I added some tips for their usage and further details on their subcommands
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:
tl;dr
Don't forget
require 'English'
if you use a named global such as$LAST_MATCH_INFO
. Otherwise this could result in an annoying bug.
With Ruby's build-in library English you can reference global variables with an english name. This makes you code easier to read and is also suggested by Rubocop's Style/GlobalVars cop.
Example before:
if 'foo' =~ /foo/
puts $~[1] # => foo
end
Example af...
Or: How to avoid and refactor spaghetti code
Please note that I tried to keep the examples small. The effects of the methods in this card are of course much more significant with real / more complex code.
Code is written once but read often (by your future self and other developers who have to understand it in order to make changes for example). With more modular code you reduce the scope of what has to be understood in order to change something. Also, naming things gives you the opportunity t...
I recently noticed that better_errors
allows you to to open files from within your favorite editor. However it was not so easy to get rubymine://
links to work on Gnome/Linux. Here is how it finally worked for me:
Add this file to ~/.local/share/applications/rubymine.desktop
:
[Desktop Entry]
Version=1.0
T...
Debugging your integration tests, that run a headless Chrome inside a docker image, is tricky.
In many cases you can connect your Chrome to a remote docker container like docker-selenium, which should be the preferred way when you try to inspect a page within your integration test.
Otherwise you might be able to start your docker container with --net=host
and access your local chromedriver in the host address space host.docker.internal
.
If both options above don't work for you here is a...