Working with or without time zones in Rails applications
Rails supports time zones, but there are several pitfalls. Most importantly because Time.now and Time.current are completely different things and code from gems might use one or the other.
Especially configuring an application that cares only about one time zone is a bit tricky.
The following was tested on Rails 5.1 but should apply to Rails 4.2 as well.
Using only local time
Your life will be easier if your application does not need to support time zones. Disable them like this:
config.time_zone = 'Berlin' # Your local ...
Local development with SSL and Puma
Sometimes the need arises for SSL in local development. We have guides for different webservers, this one is for puma.
-
make sure mkcert is installed
-
create an SSL certificate for localhost with mkcert:
$ mkcert-v1.4.4-linux-amd64 localhost
Created a new local CA 💥
...
- use the certificate in the Puma config
config/puma.rb:
localhost_key = "#{File.join('localhos...
Yarn: Use yarn-deduplicate to cleanup your yarn.lock
Note
Use
yarn dedupein Yarn v2+: https://yarnpkg.com/cli/dedupe
This package only works with Yarn v1. Yarn v2 supports package deduplication natively!
A duplicate package is when two dependencies are resolved to a different version, even when a single version matches the range specified in the dependencies. See the Deduplication strategies section for a few examples.
Yarn is stupid, so it can happen that there are several version of the same package in your bundle, although one would fulf...
Rails: Do not load frameworks you don't need
Rails is split into a large number of (sub-) frameworks.
The most important and central of those are
- activesupport (extends the Ruby standard library)
- activerecord / activemodel (ORM for Rails)
- actionview / actionpack (controller / views)
- actionmailer (sends mails)
However, there are also some more situational frameworks included, such as
- actioncable (real time communications using websockets)
- actionmailbox (receives mails)
- actiontext (support for WYSIWYG text editor)
- activejob (background jobs)
- activestorage (file uplo...
CSS: :is() pseudo selector
tl;dr
The
:is()pseudo selector - specificity of its most specific argument - matches against a comma-separated list of selectors.
Example
Compound selectors like ...
.datepicker .prev, .datepicker .next, .datepicker .switch
padding-bottom: 1rem
ul li, ol li
list-style-type: none
can be simplified by using the :is() pseudo selector ...
.datepicker :is(.prev, .next, .switch)
padding-bottom: 1rem
:is(ul, ol) li
list-style-type: none
Hint
The specificity of
:is()is equals t...
CSS: :where() pseudo selector
tl;dr
The
:where()pseudo selector - zero specificity - matches against a comma-separated list of selectors.
Example
Compound selectors like ...
.datepicker .prev, .datepicker .next, .datepicker .switch
padding-bottom: 1rem
ul li, ol li
list-style-type: none
can be simplified by using the :where() pseudo selector ...
.datepicker :where(.prev, .next, .switch)
padding-bottom: 1rem
:where(ul, ol) li
list-style-type: none
Hint
The specificity of
:where()is always zero!I...
Rails: How to check if a certain validation failed
If validations failed for a record, and you want to find out if a specific validation failed, you can leverage ActiveModel's error objects.
You rarely need this in application code (you usually just want to print error messages), but it can be useful when writing tests.
As an example, consider the following model which uses two validations on the email attribute.
class User < ApplicationRecord
validates :email, presence: true, uniqueness: true
end
Accessing errors
Let's assume we have a blank user:
user = Us...
Generating and streaming ZIP archives on the fly
When your Rails application offers downloading a bunch of files as ZIP archive, you basically have two options:
- Write a ZIP file to disk and send it as a download to the user.
- Generate a ZIP archive on the fly while streaming it in chunks to the user.
This card is about option 2, and it is actually fairly easy to set up.
We are using this to generate ZIP archives with lots of files (500k+) on the fly, and it works like a charm.
Why stream downloads?
Offering downloads of large archives can be cumbersome:
- It takes time to b...
Cucumber pitfall: "Around" does not apply to your "Background" steps
Around will not happen until after a feature's Background has been processed. Use Before and After to avoid that.
Details
Consider this Cucumber feature file:
Feature: Something that needs to be tested
Background:
Given a user
And I sign in
Scenario: Sign out
When I sign out
Then I should see "Signed out"
Scenario: Something else
# ...
Now, assume you have these step definitions:
Around do
puts "** Around: before yield"
...
Valuable Chrome DevTools Shortcuts
In the DevTools settings, there's a "Shortcuts" section. Found these keyboard shortcuts there:
General
ESC
Toggle drawer
CTRL + ~ or CTRL + `
Show console in drawer
Styles
SHIFT + up/down
Change number by 10
CTRL + up/down
Change number by 100
Elements
H
Toggle "visibility:hidden!important" (useful when debugging page repaint times)
CTRL + hover above element in the DOM list
Don't show the yellow dimensions tooltip (useful when the tooltip covers just the area you need to see).
Drag...
A short overview of common design patterns implemented within Rails
The linked content includes a few design patterns implemented with Ruby on Rails.
What is the card indented to achieve?
- You can use the pattern names for code reviews, so all parties know with only a few words which change is requested. Example: "Please use a form object here"
- You can learn about new code patterns
- You should read the sections "Advantages of using design patterns" and "Disadvantages of using design patterns in a wrong way", since design patterns do not replace good code
Included Design Patterns: Service, Value objec...
makandra tech survey - results
These are the results of the "personal tech stack survey". I've included only the most popular mentions, maybe it can help you find one or two useful tools for your own usage.
Desktop environment
pie title Desktop environment
"Gnome" : 16
"i3": 2
"sway": 2
"awesome": 1
"bspwm": 1
"mate": 1
"xfce": 1
Gnome dominates (unsuprising, it's the Ubuntu default), but quite a few people use tiling window managers, most popular i3 and the mostly i3-compatible [sway](https://swaywm....
Fix for mysql2 error "Incorrect MySQL client library version! This gem was compiled for x.x.x but the client library is y.y.y."
This should be fixed in the latest LTS-branches of our mysql2 fork, 0.2.x-lts and 0.3.x-lts.
Use
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.2.x-lts' # for Rails 2.x
gem 'mysql2', git: 'https://github.com/makandra/mysql2', branch: '0.3.x-lts' # for Rails 3.x
in your Gemfile, and do a
bundle update mysql2
Background
mysql2 used to check that the client library used at runtime actually matches the one it was compiled against. However, at least on Ubunt...
Reading the Rails session hash from a Rack middleware
To read the Rails session from a Rack middleware, use env['rack.session']. It's an ActionDispatch::Request::Session object.
class MyMiddlware
def initialize(app)
@app = app
end
def call(env)
status, headers, body = @app.call(env)
session = env['rack.session']
Rails.logger.info("Value of session['foo'] is: " + session['foo'].inspect)
[status, headers, body]
end
end
You may not be able to write to the session this way (I haven't tested this).
Fixing flaky E2E tests
An end-to-end test (E2E test) is a script that remote-controls a web browser with tools like Selenium WebDriver. This card shows basic techniques for fixing a flaky E2E test suite that sometimes passes and sometimes fails.
Although many examples in this card use Ruby, Cucumber and Selenium, the techniques are applicable to all languages and testing tools.
Why tests are flaky
Your tests probably look like this:
When I click on A
And I click on B
And I click on C
Then I should see effects of C
A test like this works fine...
Fix: esbuild assets are missing after capistrano deploy
Issue: You have an app using jsbundling-rails and esbuild. After deploy, the assets built by esbuild are missing in public/assets.
Solution: Add app/builds to your git repo (by adding a app/builds/.keep file).
Something in sprockets is caching paths and refuses to accept files in "unknown" locations.
Writing strings as Carrierwave uploads
When you have string contents (e.g. a generated binary stream, or data from a remote source) that you want to store as a file using Carrierwave, here is a simple solution.
While you could write your string to a file and pass that file to Carrierwave, why even bother? You already have your string (or stream).
However, a plain StringIO object will not work for Carrierwave's ActiveRecord integration:
>> Attachment.create!(file: StringIO.new(contents))
TypeError: no implicit conversion of nil into String
This is because Carrierwav...
PostgreSQL: How to show database size
SELECT pg_size_pretty(pg_database_size('some-database'));
Example
SELECT pg_size_pretty(pg_database_size('cards_p'));
----------------
13 GB
(1 row)
SELECT pg_database_size('cards_p');
pg_database_size
------------------
13524832927
(1 row)
Related
The Easiest Way to Parse URLs with JavaScript
A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.
You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:
var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'
if (pathname[0] != '/')
pathname = '/' + pathname // Fix IE11
One advantag...
Icon font vertical alignment in Windows
I had an issue with icons from an icon font aligning differently on Linux, iOS and Windows (seemingly browser-independent). With vertical-align:middle, they aligned properly on Linux, iOS and macOS, whereas with a vertical-align of -18%, it looked good on Windows and iOS, but not Linux.
Further investigation showed that not only icons, but also normal capital letters aligned differently. No setting of vertical-align could fix this, neither top, bottom, middle, nor additional paddings or margins. It seems like browsers take the...
Hiding the clear input button of Edge (with EdgeHTML engine)
Edge (and some versions of Internet Explorer, like IE11) use to render a × clear input button on text fields. While this is intended as a nicety for users, it comes in annoying when you've built and styled your own clear input button.
Hide the Edge × with this pseudo selector:
input::-ms-clear
display: none
Double loading issue with Ruby default gems
Ruby includes many standard gems that are bundled into the Ruby installation. Here is an example for the gem strscan that will be displayed as default:
gem list strscan
*** LOCAL GEMS ***
strscan (default: 3.0.1)
It is still possible to have newer version of a gem installed beside the default version:
gem install strscan
Fetching strscan-3.0.3.gem
Building native extensions. This could take a while...
Successfully installed strscan-3.0.3
1 gem installed
gem list strscan
*** LOC...
How to debug issues with zeitwerk and Rails
In case you have trouble with the zeitwerk autoloader, you can check out the documentation Autoloading and Reloading Constants and Classic to Zeitwerk HOWTO for some debugging hints.
For myself it was useful to print the registered constants and the file references during the boot. Therefore you need to add Rails.autoloaders.log! at the end of your config/application.rb file. You could also run `bin...