Geordi 5.4.0 released
5.4.0 2021-02-01
Compatible changes
- Add
geordi branchcommand that checks out a feature branch based on a story from Pivotal Tracker - Faster MySQL dumping with
--single-transactionand--quick - Allow pivotal tracker ids in the global config file
- Fix missing require for
Fileutilsin the dump load command (#145) - Document
PARALLEL_TEST_PROCESSORS
Parsing JSON with edge cases
The linked article shows that there are unclear parts in the JSON specification and that different parsers treat them differently (which could lead to security vulnerabilities in certain cases).
I was curious what Ruby does (Ruby 2.6.6 with gem json 2.3.0, implementing RFC 7159):
Duplicate Keys
irb(main):001:0> require 'json'
=> true
irb(main):002:0> JSON.parse('{"qty": 1, "qty": -1}')
=> {"qty"=>-1}
Character Collision
irb(main):009:0> JSON.parse('{"qty": 1, "qty\ud800": -1}')
JSON::ParserError (487: incomplete sur...
Webmock < 3.12.1 cannot handle IPv6 addresses correctly
We had the issue, that a VCR spec failed, after updating CarrierWave from version 0.11.0 to 1.3.2.
In this version, CarrierWave uses the gem SsrfFilter, which retrieves the IP addresses for the given hostname and replaces the hostname in the requested url with one of them.
It works with IPv4 addresses, but not with IPv6 addresses, because WebMock cannot handle those correctly:
uri = "#{protocol}://...
Making ZSH the default shell on Ubuntu 20.04
ZSH is an alternative command line shell that includes some features like spelling correction, cd automation, better theme, and plugin support. You can replace Bash with ZSH like following:
sudo apt-get install zsh
Setting ZSH as default login shell
sudo usermod -s /usr/bin/zsh $(whoami)
Opening a new terminal window will show you a dialog where you can configure your initial ZSH config (Option 2 recommended).
Afterwards you can install the plugin manager Oh-My-ZSH and select a prop...
Mixed Content Examples
The pages […] allow you to see different types of mixed content and test how they behave in your browser. The "Secure" pages are referencing assets with HTTPS, the "Non-Secure" pages are referencing them with HTTP. Generally, you'll observe the same behavior with both Secure pages and the Secure HTTP page for a given test; the behavior will change on the Non-Secure HTTPS page.
Also see Testing HTTPS with badssl.com.
Rails: Parsing a time in a desired timezone
Sometimes you want to have a time in a given timezone independent from you Rails timezone settings / system timezone. I usually have this use case in tests.
Example
Time.parse('2020-08-09 00:00') will return different results e.g. 2020-08-09 00:00:00 +0200 depending on the Rails timezone settings / system timezone. But in this example we always want to have the given time in UTC because that's what the API returns.
it 'returns a valid API response', vcr: true do
expect(client.get('/users/1')).to have_attributes(
name: 'So...
How to fix: WrongScopeError when using rspec_rails with Rails 6.1
tl;dr: Upgrade the gem to at least 4.0.1
When you use rspec_rails in a version < 4 with Rails 6.1 you may encounter an error like this:
Failure/Error:
raise WrongScopeError,
"`#{name}` is not available from within an example (e.g. an " \
"`it` block) or from constructs that run in the scope of an " \
"example (e.g. `before`, `let`, etc). It is only available " \
"on an example group (e.g. a `describe` or `context` block)."
`name` is not available from within an example (e.g. an `it` block) or from constructs that...
Best practices for REST API design
A rough guide how to implement a REST API.
The discussion here includes some interesting points as well:
- Timestamps: ISO8601 format ("2021-02-22T20:34:53.686Z")
- Google API guideline: https://google.aip.dev/
- Numbers: String vs. Number
The JSON number type is not a double. It's just a number of arbitrary size and precision in integer/decimal/E format that can be parsed as whatever the parser finds fitting.
- Pagination: Limit + Offset vs. Object ID / Pointer vs. System-Version...
Running old ImageMagick versions in a Docker container
If your project depends on an old version of ImageMagick that you can no longer install in your system, you can choose the run an old ImageMagick in a Docker container.
Dockerized ImageMagick commands will only work with absolute path arguments. You need to boot a corresponding docker container once before using it.
Setting up Docker
If you haven't installed Docker yet, use our guide or the [official instructions](https://docs.docker.com/get-started/...
Make your Rails console (and irb) output better readable
Pour color on your Rails console with awesome_print. Turn confusing long strings into formatted output. Have objects and classes laid out clearly whenever you need it.
Put gem 'awesome_print', :group => :development into your Gemfile. Now on the Rails console you have the command ap that will give you a colored, formatted output of whatever you pass it. See the example output of the User class below.
For customization visit the repository on Github.
 and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/
...
WYSIWYG with Action Text
Rails 6 includes a WYSIWYG editor, Action Text. It works out of the box quite well, but chances are that you want to add some custom functionality. This card contains some tips how to achieve this.
Setup
Basically, follow the guide in the Rails documentation. The automated script may not work with the way webpacker is configured in your project, but it should be easy to fix.
If you don't want the default c...
Rails: Postgres Partial Indexing
PostgreSQL has partial indexes. With a partial index you tell Postgres to only index rows matching a given query.
Some uses cases for a partial index:
- You want a uniqueness index, but only under some conditions
- Your table is very large and indexing every row becomes expensive
The linked article shows how to create a partial index with Rails.
How to fix "Command "webpack" not found"
I just ran into this deployment error after switching from the asset pipeline to webpack:
01:05 deploy:assets:precompile
01 bundle exec rake assets:precompile
01 Compiling...
01 Compilation failed:
01 yarn run v1.22.5
01 error Command "webpack" not found.
rake stderr: Nothing written
The problem is not related to the "webpack" dependency. You probably just forgot to add a binstub to run "yarn install":
Add these lines to "bin/ya...
InfoQ: How to Design a Good API & Why it Matters
A well-written API can be a great asset to the organization that wrote it and to all that use it. Given the importance of good API design, surprisingly little has been written on the subject. In this talk (recorded at Javapolis), Java library designer Joshua Bloch teaches how to design good APIs, with many examples of what good and bad APIs look like.
Rails: How to use custom flash types in controllers
Rails supports alert and notice as default flash types. This allows you to use these keys as options in e.g. redirect_to and as a helper in views e.g. <%= notice %> (instead of flash[:notice]).
class SomeController < ApplicationRecord
def create
@user = User.create!
redirect_to user_path(@user), notice: "#{@user} created!"
end
end
In case you are using Bootstrap as CSS framework you might also want to support flashes like success. This can be done with the add_flash_types method.
class Applicat...
Git: Parsing large diffs as a human
I just finished migrating a project from the Asset Pipeline to Webpacker, this is what my diff to master looks like:
5.825 files changed, 44.805 insertions(+), 529.948 deletions(-)
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 5134 and retry the command.
There is no way me or my peer reviewer is able to parse 500k+ lines of code. Fortunately, git has ...
Ruby: How to load a file with a known encoding
In case Ruby does not detected the expected encoding of a file automatically you can specify the known encoding manually.
Example with File.open
file = File.open('some.bin', encoding: Encoding::ASCII_8BIT)
text = file.read
text.encoding => #<Encoding:ASCII-8BIT>
Example with File.read
text = File.read('some.bin', encoding: Encoding::ASCII_8BIT)
text.encoding => #<Encoding:ASCII-8BIT>
More details about the encoding of strings in Ruby can be found [here](https://makandracards.com/makandra/474671-guide-to-string-encodi...
Fixing memory leaks in the browser
In my experience, the most common sources of memory leaks are APIs like these:
- addEventListener. This is the most common one. Call removeEventListener to clean it up.
- setTimeout / setInterval. If you create a recurring timer (e.g. to run every 30 seconds), then you need to clean it up with clearTimeout or clearInterval. (setTimeout can leak if it’s used like setInterval – i.e., scheduling a new setTimeout inside of the setTimeout callback.)
- IntersectionObserver, ResizeObserver, MutationObserver, etc. The...
How to communicate between processes in Ruby with sockets
In Ruby you can communicate between processes with sockets. This might be helpful in tests that validate parallel executions or custom finalization logic after the garbage collector. Here is an example how such an communication will look like:
require 'socket'
BUFFER_SIZE = 1024
# DGRAM has the advantage that it stops reading the pipe if the next messages starts. In case the message size is larger than the
# BUFFER_SIZE, you need to handle if you are reading another part of the current message or if you already reading the
# next mess...
ExceptionNotification: Fix DNS lookup before plugins call external APIs
The ExceptionNotification has plugins that talk to external APIs rather then just sends emails, like microsoft teams or slack. You might encounter that no exceptions are delivered, which can be dangerous.
To prevent getting into trouble, simply add require 'resolv-replace' on top of your to your initializers/exception_notification.rb file:
require 'resolv-replace'
require 'exception_notification/rails'
ExceptionNotification.configure do |config|
...
end
This calls the Ruby DNS resolver before configuring `ExceptionNot...
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...