HTML emails with inline stylesheets and webpacker
Many mail clients do not support external style sheets. Some even require all styling inline, which means you'll have to do your styling inline. For Rails applications, you can use Roadie or premailer, which lets you keep your well-structured CSS files and do the inlining for you.
Since Roadie is now in passive maintenance mode, we go with premailer:
Include premailer in your Gemfile:
gem 'premailer-ra...
Migration from the Asset Pipeline to Webpacker
This is a short overview of things that are required to upgrade a project from the Asset Pipeline to Webpacker. Expect this upgrade to take a few days even the diff is quite small afterwards.
Preparations
1. Find all libraries that are bundled with the asset pipeline. You can check the application.js and the application.css for require and import statements. The source of a library is most often a gem or a vendor directory.
2. Find an working example for each library in the application and write it down.
3. Find out the ver...
MySQL: How to create columns like "bigint" or "longtext" in Rails migrations, and what :limit means for column migrations
Rails understands a :limit options when you create columns in a migration. Its meaning depends on the column type, and sometimes the supplied value.
The documentation states that :limit sets the column length to the number of characters for string and text columns, and to the number of bytes for binary and integer columns.
Using it
This is nice since you may want a bigint column to store really long numbers in it. You can just create it by ...
During deployment: "You are trying to install in deployment mode after changing your Gemfile"
While deploying an Ruby update to an old application these days, we encountered the following misleading error:
*** [err :: some-host.makandra.de] You are trying to install in deployment mode after changing
*** [err :: some-host.makandra.de] your Gemfile. Run `bundle install` elsewhere and add the
*** [err :: some-host.makandra.de] updated Gemfile.lock to version control.
*** [err :: some-host.makandra.de]
*** [err :: some-host.makandra.de] You have deleted from the Gemfile:
*** [err :: some-host.makandra.de] *
We found out a newe...
How to doubleclick in Selenium
Put the attached file into features/support/.
Example usage:
When /^I open the task named "(.+?)"$/ do |task_name|
task = page.all('.task').detect do |t|
t.find('.label').text.downcase == task_name.downcase
end
task.double_click
end
Note: only Selenium understands doubleclicks.\
Credits: the attached Capybara issue discussion.
Why you can't use timezone codes like "PST" or "BST" for Time objects
Rails' ActiveSupport::TimeWithZone objects have both a timezone code and offset, e.g. Thu, 28 Mar 2019 16:00:00 CET +01:00. Ruby's stdlib TZInfo also has time zones, but with different identifiers.
Unfortunately, not all timezone codes can be used to parse strings or to move time objects into another time zone.
Some timezone codes like CET are supported by ActiveSupport extensions like String#in_time_zone, while many codes will actually not work:
>> '2019-03-01 12:00'.in_time_zone('PST')
ArgumentError (Invalid Timezone: PST)
...
Git: Revert one or more commits
Reverting a commit means creating a new commit that undoes the old changes.
Imagine the following commit history:
* commit_sha3 [Story-ID 1] Fixup for my feature
* commit_sha2 [Story-ID 5] Other feature
* commit_sha1 [Story-ID 1] My feature
You can revert a single commit using the following syntax:
git revert commit_sha2
To revert changes that are split across multiple commits, use the --no-commit flag.
git revert --no-commit commit_sha3
git revert --no-commit commit_sha1
git commit -m "Revert Story 1"
CSS: Flex and "min-width"
min-width is known as a CSS property that can be set to define a least width for an element. Surprisingly, it can also be used to set something that feels like max-width.
min-width in a flex context
While the default min-width value is 0 (zero), for flex items it is more like "auto". This can make block elements take up much more space than desired, even stretching their container beyond the screen edge on small screens.
 fonts in an application with Webpack(er), we have two options. We can
- put the fonts directly into your Webpack's assets folder or
- write an npm package with an own sass file that can be imported from the Webpack manifest.
Load fonts from your assets folder
The first option turns out to be straightforward: Import the stylesheets in the index.js of the pack you're using:
// webpack_source_path/application/index.js
import './stylesheets/reset'
import...
rails_state_machine 1.1.2 released
Fixed bugs where calling valid? would change the record's state.
How to fix parallel_tests with Redis on powerful machines
When you have a powerful machine with many CPU cores, you might run into an error like
ERR DB index is out of range (Redis::CommandError)
This is because Redis defaults to at most 16 databases (0 to 15) and running tests in parallel might exceed that (your tests might run on databases 1..n or 2..(n+1)).
You can increase that limit:
-
Get number of CPUs of your machine.
nproc --all -
Open up Redis configuration file.
sudo vim /etc/redis/redis.conf -
Find
databasesrow and increase it, e.g. set to 32:
...
How to fix: Session hash does not get updated when using "merge!"
tl;dr: Do not use merge! for session hashes. Use update instead.
Outline
Let's assume you're modifying the Rails session. For simplicity, let's also assume your session is empty when you start (same effect when there is data):
# In our example, we're in a Rack middleware
request = Rack::Request.new(env)
request.session.merge! :hello => 'Universe'
request.session
=> {}
Even worse: When you inspect your request.session like above (e.g. in a debugger shell, o...
Bootstrap 4 skin for the Rome datepicker
Here is how to make Rome datepicker look like the rest of your Bootstrap 4 application.
Rome comes with very little basic styling. While we could redefine its classes, we can configure the classes Rome applies to its elements to make it look like this:
Since Bootstrap 4 comes with several helpful utility classes, and requires fewer markup/containers, we can achieve Bootstrap 4 experience by applying a few classes via the styles setting.
You still need to include `ro...
Upgrade guide for moving a Rails app from Webpack 3 to Webpack 4
Webpacker is Rails' way of integrating Webpack, and version 4 has been released just a few days ago, allowing us to use Webpack 4.
I successfully upgraded an existing real-world Webpack 3 application. Below are notes on everything that I encountered.
Note that we prefer not using the Rails asset pipeline at all and serving all assets through Webpack for the sake of consistency.
Preparations
- Remove version locks in
Gemfileforwebpacker - Remove version locks in
package.jsonforwebpackandwebpack-dev-server - Install by ca...
Rails: How to get URL params without routing parameters (or vice versa)
Rails' params hash contains any request parameters (URL parameters or request payload) as well as routing parameters like :controller, :action, or :id.
To access only URL parameters, use request.query_parameters. Routing params are available through request.path_parameters.
# On /users?query=Bob&page=2
>> request.params
=> {"page"=>"2", "query"=>"Bob", "controller"=>"users", "action"=>"index"}
>> request.query_parameters
=> {"page"=>"2", "query"=>"Bob"}
>> request.path_parameters
=> {:controller=>"users", :action=>"i...
Micro clearfix mixin for Sass
Clearfix is a hack to clear floating elements without additional HTML markup.
If you only need to support IE8 and above, a great clearfix with few side effects is:
=clearfix
&:after
content: ""
display: block
clear: both
This is a Sass mixin.
Issues clearing with display: table
You will find many clearfix solutions that clear with display: table instead:
=clearfix
&:after
content: ""
display: table
clear: both
The problem with th...
Copy to clipboard without flash (clipboard.js)
We used zeroclipboard.js in some of our projects but now we switched to clipboard.js because it does not rely on flash. Flash support of the major browsers has ended.
Some more advantages of clipboard.js:
- it consists only of a single javascript file, so it does not trigger additional requests with rails
- it automagically provides user feedback by selecting the text it has copied
- it provides callbacks for success and error which make it easier to add custom behaviour after copying to the clipboar...
JavaScript without jQuery
This is a presentation from 2019-01-21.
Summary
- We want to move away from jQuery in future projects
- Motivations are performance, bundle size and general trends for the web platform.
- The native DOM API is much nicer than it used to be, and we can polyfill the missing pieces
- Unpoly 0.60.0 works with or without jQuery
Is jQuery slow?
From: Sven
To: unpoly@googlegroups.com
Subject: performance on smartphones and tablets
Hello
I just used your framework in one project and must say,
I am really pleased with it -- but o...
How to install bundler for Ruby < 2.3
Bundler 2 requires at least Ruby 2.3.0 and RubyGems 2.5.0. You might get the following error when you try to install bundler for Ruby < 2.3:
ERROR: Error installing bundler:
bundler requires Ruby version >= 2.3.0.
To fix this error upgrade your project's ruby version or install the last supported version of Bundler for Ruby < 2.3:
gem install bundler -v '~>1'
You will also see an error if your [RubyGems versi...
AngularJS 1: How to keep "ng-hidden" elements from flickering on page load
When you have an element you want to hide, you can add a ng-show='isOpen' attribute to that element. When you set isOpen to false on the scope, the element will be hidden.
However, when you load the page, the element is usually rendered by the browser before Angular has loaded and had a chance to hide it.
Generic fix (prefer)
The ng-cloak directive was designed for exactly this purpose. Add a ng-cloak attribute or class (and more, see the link) to any element you want to ...
Carrierwave: Built-in resize methods
Carrierwave includes some handy helper methods you can use to resize your images. Here is a quick summary of them, if you need more details read the docs. You can also use all command line options from RMagick directly if these helpers are not good enough for you.
resize_to_limit(width, height)
resize_to_fit(width, height)
resize_to_fi...
Trigram indexing as an alternative to PostgreSQL fulltext search
For searching in large database tables we usually use PostgreSQL's fulltext search capabilities.
While this works reasonably well for content primarily consisting of prose, it is not necessarily a good solution for all use cases. The main issue is that it is only possible to search for prefixes of text tokens, which can potentially be unexpected for users.
One example are dates:
If you index the text 2019-01-23 15:16, PostgreSQL will create the following tokens: 2019, -01, -23, 15 16. A user searching for 01-23 wi...
How to drop all tables in PostgreSQL
To remove all tables from a database (but keep the database itself), you have two options.
Option 1: Drop the entire schema
You will need to re-create the schema and its permissions. This is usually good enough for development machines only.
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
Applications usually use the "public" schema. You may encounter other schema names when working with a (legacy) application's database.
Note that f...