Webmock normalizes arrays in urls
Typhoeus has a different way of representing array params in a get
request than RestClient.
Typhoeus: http://example.com/?foo[0]=1&foo[1]=2&foo[2]=3
RestClient: http://example.com/?foo[]=1&foo[]=2&foo[]=3
Webmock normalizes this url when matching to your stubs, so it is always http://example.com/?foo[]=1&foo[]=2&foo[]=3
. This might lead to green tests, but in fact crashes in real world. Rack::Utils.build_nested_query
might help to build a get re...
Middleman configuration for Rails Developers
Middleman is a static page generator that brings many of the goodies that Rails developers are used to.
Out of the box, Middleman brings Haml, Sass, helpers etc. However, it can be configured to do even better. This card is a list of improvement hints for a Rails developer.
Gemfile
Remove tzinfo-data
and wdm
unless you're on Windows. Add these gems:
gem 'middleman-livereload'
gem 'middleman-sprockets' # Asset pipeline!
gem 'bootstrap-sass' # If you want to use Bootstrap
gem 'byebug'
gem 'capistrano'
gem 'capistrano-mid...
Capistrano 3: How to deploy when a firewall blocks your git repo
Sometimes, through some firewall or proxy misconfiguration, you might have to deploy to a server that cannot access the git repository.
Solution 1: HTTP Proxy (this is the preferred fix)
SSH can be tunneled over an HTTP Proxy. For example, when the repo is on github
, use this:
-
Install
socat
-
Add a
~/.ssh/config
on the target server(s) with permission 0600 and this content:Host github.com ssh.github.com User git Hostname ssh.github.com Port 443 ProxyCommand socat - PROXY:<your proxyhost>:%h:%p,...
Quickly printing data in columns on your Ruby console
Dump this method into your Ruby console to quickly print data in columns. This is helpful for e.g. comparing attributes of a set of Rails records.
def tp(objects, *method_names)
terminal_width = `tput cols`.to_i
cols = objects.count + 1 # Label column
col_width = (terminal_width / cols) - 1 # Column spacing
Array(method_names).map do |method_name|
cells = objects.map{ |o| o.send(method_name).inspect }
cells.unshift(method_name)
puts cells.map{ |cell| cell.to_s.ljust(col_width) }.join ' '
end
nil
end
Usag...
Style Guide for Git commit messages
- Separate subject from body with a blank line
- Limit the subject line to 50 characters (max. 72), include reference (unique story ID) to requirements tracker (Linear in our case)
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line
- Wrap the body at 72 characters
- Use the body to explain what and why vs. how.
Tip
As an alternative, use a commit message that refers to a GitHub issue (
fixes #321
) or [story ID](https://makandracards.com/makandra/620718-b...
Using ActiveRecord with threads might use more database connections than you think
Database connections are not thread-safe. That's why ActiveRecord uses a separate database connection for each thread.
For instance, the following code uses 3 database connections:
3.times do
Thread.new do
User.first # first database access makes a new connection
end
end
These three connections will remain connected to the database server after the threads terminate. This only affects threads that use ActiveRecord.
You can rely on Rails' various clean-up mechanisms to release connections, as outlined below. This may...
RSpec: Debug flickering test suites with rspec --bisect
In modern default RSpec configurations, your tests are usually run in random order. This helps to detect "flickering" tests that only fail when run in a certain order.
The reason for this are tests that have side effects causing other tests to fail later. The hard part is to find the offending test.
Enter rspec --bisect
:
- Say you have a flickering test that passes on its own, but you just saw it fail in a full test run. At the top of the RSpec output, you will see a message like
Randomized with seed 12345
. Take a note of the number....
Howto: Require a gem that is not in Gemfile
In case you want to require a gem, that is not in the Gemfile of you bundle and therefore not in your loadpath, you need to add the path manually and require the gem afterwards.
Expected error
Requiring a gem, that is not in the Gemfile
or .gemspec
, will cause an LoadError
exception:
require 'example_gem' => LoadError: cannot load such file -- example_gem
Adding a gem to the loadpath temporary
- You need to install the
gem
gem install 'example_gem'
- Then you need to require the path where the gem was install...
Storing trees in databases
This card compares patterns to store trees in a relation database like MySQL or PostgreSQL. Implementation examples are for the ActiveRecord ORM used with Ruby on Rails, but the techniques can be implemented in any language or framework.
We will be using this example tree (from the acts_as_nested_set docs):
root
|
+-- Child 1
| |
| +-- Child 1.1
| |
| +-- Child 1.2
|
+-- ...
How to use Parallel to speed up building the same html partial multiple times (for different data)
The parallel-gem is quite easy to use and can speed up rendering time if you want to render the same partial multiple times (e.g. for rendering long lists of things).
If your parallelized code talks to the database, you should ensure not to leak database connections.
Consider you want to render a list of groups with their members as json. You can use a partial for the rendering of group members, b...
How to disable Chrome's save password bubble for Selenium tests
When filling out forms in Selenium tests, Chrome shows the (usual) bubble, asking to store those credentials.
While the bubble does not interfere with tests, it is annoying when debugging tests. Here are two ways to disable it:
Option 1: prefs
You can set profile preferences to disable the password manager like so:
prefs = {
'credentials_enable_service' => false,
'profile.password_manager_enabled' => false
}
Capybara::Selenium::Driver.new(app, browser: :chrome, prefs: prefs)
Sadly, there are no command line s...
CSS: Don't target multiple vendor-prefixed pseudo-elements in a single rule
Some pseudo-elements need to be addressed with vendor prefixes. E.g. ::selection
is not supported by Firefox, you need to use ::-moz-selection
instead.
What you cannot do is to define a single CSS rule to address both the standard and vendor-prefixed form:
::selection, ::-moz-selection {
background-color: red;
}
This rule will be ignored by all browsers. The reason is that if a browser doe...
How to make http/https requests yourself with nc/telnet/openssl
Sometimes you want/have to send specific http(s) requests. You can do that easy with curl
or just write the request yourself.
make a http request with nc
nc example.com 80
GET / HTTP/1.1
Host: example.com
# press enter
make a http request with telnet
telnet example.com 80
GET / HTTP/1.1
Host: example.com
# press enter
make https request with openssl
openssl s_client -connect example.com:443
GET / HTTP/1.1
Host: example.com
# press enter
You can specify more headers if you want:
nc example.c...
Sending errors to sentry from development
For the initial setup or changes in the sentry reporting it might be useful to enabled reporting of sentry in development. Don't commit these changes and prefer to report to the staging environment. As other developers might be confused of these errors try to given them a proper message and delete them afterwards.
- Add
config.raven_dsn = 'your-dns'
inconfig/environments/development.rb
. - Add development to existing environments in the
Raven.configure
block:config.environments = ['development', 'staging', 'production']
. - ...
How to view Image Metadata on the Linux Command Line with ImageMagick
ImageMagick has a command line tool called identify
which can read image metadata:
>identify -verbose DSC00136.JPG
Image: DSC00136.JPG
Format: JPEG (Joint Photographic Experts Group JFIF format)
Class: DirectClass
Geometry: 5472x3648+0+0
Resolution: 350x350
Print size: 15.6343x10.4229
Units: PixelsPerInch
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Red:
min: 0 (0)
max: 255 (1)
mean: 11...
Beware: Nested Spreewald patiently blocks are not patient
Note: The behaviour of Spreewald's within
step is as described below for version < 1.9.0; For Spreewald >= 1.9.0 it is as described in Solution 1.
When doing integration testing with cucumber and selenium you will often encounter problems with timing - For example if your test runs faster than your application, html elements may not yet be visible when the test looks for them. That's why Spreewald (a collection of cucumber steps) has a concept of doing things patiently
, which means a given b...
Generating barcodes with the Barby gem
Barby is a great Ruby gem to generate barcodes of all different sorts.
It includes support for QR codes via rQRCode; if you need to render only QR codes, you may want to use that directly.
Example usage
Generating a barcode is simple:
>> Barby::Code128.new('Hello Universe').to_png
=> "\x89PNG\r\n\u001A..."
Configuration
Barby supports several barcode types and you must require all necessary files explicitly.
For the example a...
Rails: Default generators
This is a visualization of the files that will be generated by some useful rails generators. Invoke a generator from command line via rails generate GENERATOR [args] [options]
. List all generators (including rails generators) with rails g -h
.
generator | model | migration | controller | entry in routes.rb
|
views | tests |
---|---|---|---|---|---|---|
scaffold | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
resource | ✔ | ✔ | ✔ ... |
SASS: Defining linear sizes
Just dumping this in case somebody might need it.
When you need a CSS value (a padding, margin, height etc) to shrink/grow proportionally with the parent element, you normally use percentage values. However, if you need specific values at two given widths, you need to turn to linear functions. The mixin below gives you just that.
// Call with two desired values at two different widths.
// Returns a calc() expression that will scale proportionally between those two.
// Example:
// Spaci...
How to show an ordered crontab
Crontabs are often unordered, especially when generated for an application where you usually group tasks by their domain/scope.
An example crontab might look like this:
# Begin Whenever generated tasks for: project100
MAILTO="log@example.com"
MAILFROM="cron@example.com"
# When server is booting up, ensure Sidekiq is running
@reboot start_sidekiq
23 8 * * * baz
30 * * * * plop
5 8 * * * bar
1 0 * * * foo
# End Whenever generated tasks for: project100
While you can human-parse this one easily, crontabs with several lines are hard ...
Haml: Prevent whitespace from being stripped in production
Disclaimer
This is not an issue in newer versions of HAML (starting with 5.0.0), as the ugly
-option was removed so that in development everything is rendered ugly, too.
Problem
When HTML is rendered from HAML in production or staging environment, whitespace is removed to reduce the download size of the resulting pages. Therefore it might happen that whitespace you see in development is missing in production or staging.
Here is an example of two inlined bootstrap buttons in a t...
Running external commands with Open3
There are various ways to run external commands from within Ruby, but the most powerful ones are Open3.capture3
and Open3.popen3
. Since those can do almost everything you would possibly need in a clean way, I prefer to simply always use them.
Behind the scenes, Open3
actually just uses Ruby's spawn
command, but gives you a much better API.
Open3.capture3
Basic usage is
require 'open3'
stdout_str, error_str, status = Open3.capture3('/some/binary', 'with', 'some', 'args')
if status.success?...
RestClient / Net::HTTP: How to communicate with self-signed or misconfigured HTTPS endpoints
Occasionally, you have to talk to APIs via HTTPS that use a custom certificate or a misconfigured certificate chain (like missing an intermediate certificate).
Using RestClient will then raise RestClient::SSLCertificateNotVerified
errors, or when using plain Net::HTTP:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Here is how to fix that in your application.
Important: Do not disable certificate checks for production. The interwebs are full of people say...
VCR: Inspecting a request
Using VCR to record communication with remote APIs is a great way to stub requests in tests. However, you may still want to look at the request data like the payload your application sent.
Using WebMock, this is simple: Make your request (which will record/play a VCR cassette), then ask WebMock about it:
expect(WebMock).to have_requested(:post, 'http://example.com').with(body: 'yolo')
Easy peasy.