Don't sum up columns with + in a SQL query if NULL-values can be present.
Don't sum up columns with +
in a sql-query if NULL
-Values can be present.
MySQL and PostgreSQL cannot sum up NULL
values with the +
value. The sum value will be NULL
.
MySQL:
mysql> select 1 + 2 + 3;
+-----------+
| 1 + 2 + 3 |
+-----------+
| 6 |
+-----------+
1 row in set (0,00 sec)
mysql> select 1 + NULL + 3;
+--------------+
| 1 + NULL + 3 |
+--------------+
| NULL |
+--------------+
1 row in set (0,00 sec)
Postgres:
test_database=# select 1 + 2 + 3;
?column?
----------
6
(1 row)
t...
How to use Ubuntu in English, but still show German formats
If you want to have an English Ubuntu UI, but still see dates, money amounts, paper formats, etc. in German formats, you can fine-tune your /etc/default/locale
like this:
LANG="en_US.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"
Make sure you have both en...
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...
Rails: Fixing the memory leak / performance issues in prepend_view_path
Recently we detected a memory leak in one of our applications. Hunting it down, we found that the memory leak was located in Rails' #prepend_view_path
. It occurs when the instance method prepend_view_path
is called in each request, which is a common thing in a multi-tenant application.
On top of leaking memory, it also causes a performance hit, since templates rendered using the prepended view path will not be cached and compiled anew on each request.
This is not a new memory leak. It was [first reported in in 2014](https://github.com/...
Showing a custom maintenance page while deploying
Note
The maintenance mode is enabled on all application server as soon as the file
/public/system/maintenance.html
is present.
Installation
Add this line to your application's Gemfile:
gem 'capistrano', '~> 3.0'
gem 'capistrano-maintenance', '~> 1.0'
Add this line to you application's Capfile:
require 'capistrano/maintenance'
Enable task
Present a maintenance page to visitors. Disables your application's web interface by writing a #{maintenance_basename}.html
file to each web server. The servers m...
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...
Use a global .gitignore file to ignore stuff from your machine
Sometimes you want git to ignore certain files that appear on your machine. You can do this in 3 ways:
- Per project, in the project's
.gitignore
file - Per project, in a local exclude file
- Globally on your machine
Downsides of per-project .gitignore
entries
While it might be tempting to set it per project (other devs might benefit from it), you
- need to do it each time for every project
- "pollute" a project's
.gitignore
file with stuff...
Running "bundle update" without arguments might break your application
Calling bundle update
(without arguments) updates all your gems at once. Given that many gems don't care about stable APIs, this might break your application in a million ways.
To stay sane, update your gems using the applicable way below:
Projects in active development
Update the entire bundle regularily (e.g. once a week). This ensures that your libraries are up-to-date while it's easy to spot major version bumps which may break the app.
Projects that have not been updated in a while
- [Update a single gem conservatively](htt...
Calling a helper method with the same name as your current partial
Partials always define a local variable with the same name as themselves. E.g. when you are in _recent_users.html.erb
, a local variable recent_users
will be defined and overshadow any helper method that is also called recent_users()
.
If you would like to use a helper method recent_users()
in a partial _recent_users.html.erb
you can say this in the partial template:
<% recent_users = self.recent_users() %>
<% recent_users.each do |user| %>
...
<% end %>
Your database tables should always have timestamps
Whenever you create a table from a database migration, remember to add updated_at
and created_at
timestamps to that table. Without those timestamps, investigating future bug reports will be hell. Always have timestamps.
Adding timestamps to new tables
When you create a table using create_table
, you can add timestamps by using the timestamps
shortcut:
class CreateEpisode < ActiveRecord::Migration
def change
create_table :episodes do |t|
t.string :name
t.timestam...
CSS: The inset CSS shorthand
The inset CSS property is a shorthand that corresponds to the top, right, bottom, and/or left properties. It has the same multi-value syntax of the margin shorthand.
Example
<div class="outer">
<div class="inner">
Some text
</div>
</div>
.outer {
background-color: cyan;
position: relative;
width: 500px;
height: 500px;
}
Top, right, bottom and left
https://jsfiddle.net/jqx68wem/
.inner {
background-color: darkCyan;
position: absolute;
top: 10px;
right: 10px;
bottom: 10p...
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.
Fix PNG colors in IE, old Safaris and new Firefoxes
Some browsers render PNG images with color profiles and other shenanigans, some don't.
The cleanest way to have consistent colors across browsers is to convert all your images to a standard color profile, strip the image's original profile and attach the standard profile.
If you can't be bothered to convert color profiles, a quicker (but less effective) method is to remove some PNG chunks from your files.
With Geordi
[Geordi](https://git...
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...