CSS: Using interaction media detection to disable hover styles for devices that have no hover
Since late 2015, all major browsers (still excluding Firefox) support pointing device media queries. These can be used to distinguish e.g. coarse from fine pointers (e.g. finger vs mouse), or a device with hover support from one without (e.g. desktop with mouse vs tablet).
Motivation
When hover styles modify the DOM, most mobile devices activate the hover styles on first tap. A second tap is required to trigger a click
. While this can be handy, at times it makes the UX worse.
Another issue with hover styles is that they tend to st...
Logic in media queries
Here is how to model basic logic in media queries.
AND
With keyword and
.
# Target viewport widths between 500 and 800px
@media (min-width: 500px) and (max-width: 800px)
OR
Comma-separated.
# Target viewport widths below 500 or above 800px
@media (max-width: 500px), (min-width: 800px)
NOT
Needs a little overhead with not all and
.
# Target devices that can't hover
@media not all and (hover)
See CSS: Using interaction media detection on why you'd need this.
Beware: Don't name a controller action "cookies"
The method cookies
is defined in the ActionController and should never be overwritten.
Bad example
class StaticPagesController < ApplicationController
def imprint
end
def cookies
redirect_to '/'
end
end
If you create an action called cookies
, any call to the cookie storage will be broken and call the method. What's more, in this example calls to static_pages_controller#imprint
might as well end up redirecting to the homepage.
Solution
Just define the action as cookies_action
or similar and adjust...
ActiveRecord::Store: migrate data in store
When you need to store structured data (like Ruby hashes) in a single database column with ActiveRecord, a simple way is to use PostgreSQL's jsonb
columns. ActiveRecord will automatically serialize and deserialize your Hash to and from JSON, and you can index JSON paths for fast reads.
As an alternative, ActiveRecord::Store
offers a way to store hashes in a single database column. This card will show you how to migrate those hashes in an ActiveRecord::Migration
by example:
...
Capistrano + Rails: Tagging production deploys
Just like Ruby Gems tag their version releases to the corresponding Git commit, it can be helpful to track production deploys within the commit history. This task does the tagging for you.
Capistrano 3
# lib/capistrano/tasks/deploy.rb
namespace :deploy do
...
desc 'Tag the deployed revision'
task :tag_revision do
date = Date.today.to_s
puts `git tag deploy-#{date} #{fetch :current_revision}`
puts `git push --tags origin`
end
end
# config/deploy/production.rb
after 'deploy:finished', 'deploy:tag_revi...
Capistrano + Rails: Automatically skipping asset compilation when assets have not changed
In medium-sized to large Rails applications, asset compilation can take several minutes. In order to speed up deployment, asset precompilation can be skipped. This card automates the process.
Capistrano 3
namespace :deploy do
desc 'Automatically skip asset compile if possible'
task :auto_skip_assets do
asset_locations = %r(^(Gemfile\.lock|app/assets|lib/assets|vendor/asset))
revisions = []
on roles :app do
within current_path do
revisions << capture(:cat, 'REVISION').strip
...
Fixing authentication in legacy applications
Authentication is hard: there are many edge cases, and most users (including yourself) usually only go the "happy path" once and never see the edge cases. If you have rolled your own authentication, or been using older authentication solutions, or resorted to HTTP Basic Authentication, this card will tell you what to do to make your application safe.
Any application that stores sensitive data in the browser
That is: cookies, e.g. by offering a login.
- Ask the admins to [turn on SSL](https://makandracards.com/makandra/1416-integrate-s...
CSS: Using the current text color for other color properties
There is a kinda secret, yet well supported CSS feature called currentColor
. It's like a special CSS variable that has been supported in almost all browsers for almost all time (see linked Caniuse).
Usage
The currentColor
value can be used in CSS to indicate the current value of color
should be used. A common use case is setting a border color:
a.ghost
color: white
border: 1px solid currentColor
&:hover
color: red // Border color will change as well
Note that in many cases, you can simply omit the color to ac...
How to create a user with all privileges to MariaDB
Create a user without password (recommended)
Replace newuser
with your desired username:
mysql -uroot -p
CREATE USER 'newuser'@'localhost' IDENTIFIED BY '';
GRANT ALL PRIVILEGES ON * . * TO 'newuser'@'localhost';
FLUSH PRIVILEGES;
exit;
Remove password from an existing user
If you already have a user with sufficient privileges but protected by a password, you can remove the password.
Replace existinguser
with your desired username:
mysql -uroot -p
SET PASSWORD FOR existinguser@localhost='';
FLUSH PRIVILEGES;
exit;...
RubyMine: Scratch files
There are times when you have a chunk of text that you want to do something with, e.g. replace something on it, or quickly edit it.
While you can open your favorite non-RubyMine editor for this, there is also a plugin: Scratch.
It allows RubyMine to open temporary files (actually they are saved, but somewhere inside the plugin's directory) so you don't need to switch to a text editor like gEdit that works differently and may not even offer what you are used to.
Note that RubyMine also offers so...
screenfull.js: Simple wrapper for cross-browser usage of the JavaScript Fullscreen API
Using the JS fullscreen API is painful because all browers use different methods and events and you need to use lots of boilerplate code to make your application work in all browsers.
The "screenfull" library wraps that for you, including events.
Examples
The linked GitHub repo contains some information. You basically use the library like this:
// Make an element go fullscreen
screenfull.request(element)
// Leave fullscreen
screenfull.exit()
...
Capistrano task to tail remote application logs of multiple servers
When your application is running on a multi-server setup, application logs are stored per server (unless you choose a centralized logging solution).
Here is a Capistrano task that connects to all servers and prints logs to your terminal like this:
$ cap production app:logs
00:00 app:logs
01 tail -n0 -F /var/www/your-application/shared/log/production.log | while read line; do echo "$(hostname): $line"; done
01 app01-prod: Started GET "/sign_in" for 1.2.3.4 at 2018-04-26 11:28:19 +0200
01 app01-prod: Proc...
How to make Capistrano not truncate server output
By default, Capistrano truncates server responses and places an ellipsis at the end of lines that are longer than your terminal. Error messages are never truncated.
While this can be helpful to make deployment output appear less noisy, it also hides information that could be helpful.
I believe you should prefer knowing what is going on, even if causes a few extra lines of output.
Capistrano by default uses Airbrussh which is where truncation happens. To disable truncation globally, place this into your deploy.rb
:
set :format_options...
Unpoly: Loading large libraries on-demand
When your JavaScript bundle is so massive that you cannot load it all up front, I would recommend to load large libraries from the compilers that need it.
Compilers are also a good place to track whether the library has been loaded before. Note that including same <script>
tag more than once will cause the browser to fetch and execute the script more than once. This can lead to memory leaks or cause duplicate event handlers being registered.
In our work we mostly load all JavaScript up front, since our bundles are small enough. We recent...
jQuery: How to replace DOM nodes with their contents
You know that you can use jQuery's text()
to get an element's contents without any tags.
If you want to remove only some tags, but keep others, use contents()
and unwrap()
. Here is how.
Consider the following example element.
$container = $('<div><strong>Hello</strong> <em>World</em></div>')
Let's say we want to discard any <em>
tags, but keep their contents.
Simply find
them, then dive into their child nodes via contents
, and use unwrap
replace their ...
ActionMailer: How to send a test mail directly from the console
If your rails application is unable to send mails, it might be useful to debug your settings using the rails console. Here is a snippet that shows the current settings and lets you send a test mail directly from the console:
mailer = ActionMailer::Base.new
# check settings:
mailer.delivery_method # -> :smtp
mailer.smtp_settings # -> { address: "localhost", port: 25, domain: "localhost.localdomain", user_name: nil, password: nil, authentication: nil, enable_starttls_auto: true }
# send mail:
mailer.mail(from: 'sender@example.com', ...
PostgreSQL: How to show table sizes
When you have a large PG database, you may want to find out which tables are consuming the most disk space.
You can easily check this using the following SQL statement from the PostgreSQL wiki.
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
AND C.relkind <> 'i'
AND nspname !~ '^pg_toast'
ORDER BY pg_tot...
Persist Rails or IRB Console Command History After Exit
Create, or edit your ~/.irbrc
file to include:
require 'irb/ext/eval_history' # was 'irb/ext/save-history' for versions prior to Ruby 3.3
IRB.conf[:SAVE_HISTORY] = 2000
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"
Understanding IRB warning "can't alias ... from ..."
Sometimes, the IRB prints a warning during boot:
irb: warn: can't alias source from irb_source.
Explanation
During boot, the IRB creates many aliases to give the user quick access to irb functions like source
-ing a file.
However, if IRB's context already responds to the alias it wants to create, it will no...
Bundler error: Downloading gem revealed dependencies not in the API
Recent Bundler (1.16.1) started complaining about missing dependencies in the Gemfile. This is due to a stricter handling of specifications (see attached link).
The error message looks like this:
Downloading example-gem-1.2.3 revealed dependencies not in the API or the lockfile (other-gem (< 3)).
Either installing with `--full-index` or running `bundle update example-gem` should fix the problem.
However, bundle install --full-index
did not any better for me, and bundle update
is not always a viable solution.
Easiest solut...
Rails: How to provide a public link in a mail
Lets say we have a user
with a contract
whereas contract
is a mounted carrierwave file.
Now we want to send the link to the contract in a mail. For this use case join the root_url
with the public contract path in the mailer view:
Plain text email
URI.join(root_url, @user.contract.url)
HTML email
link_to('Show contract', URI.join(root_url, @user.contract.url).to_s)
Note: You need to follow [http://guides.rubyonrails.org/action_mailer_basics.html#g...
Fixing: Gem::Package::PathError: installing into parent path is not allowed
This might be a known issue with Rubygems 2.5.1. This will help:
gem update --system
Two CSS layouting techniques compared: Flexbox vs. Grid
CSS Flexbox has become extremely popular amongst front-end developers the last couple of years. This isn’t surprising, as it has made it a lot easier for us to create dynamic layouts and align content within containers.
However, there’s a new kid in town called CSS Grid, and it’s got a lot of the same capabilities as Flexbox. In come cases it’s better than Flexbox, while in other cases it’s not.
If you are to take one lesson from this article, let it be this one:
Flexbox is made for one-dimensional layouts and Grid is made for tw...