Spreewald: Content-Disposition not set when testing a download's filename
Precondition
- You are not using javascript tests
- The file is served from a public folder (not via controller)
Problem description
If you deliver files from a public folder it might be that the Content-Disposition
header is not set. That's why the following spreewald step might raise an error:
Then I should get a download with filename "..."
expected: /filename="some.pdf"$/
got: nil (using =~) (RSpec::Expectations::ExpectationNotMetError)
Solution
One solution...
Capybara steps to match stuff within any selector
These steps are now part of Spreewald.
Since Capybara 0.4.1 a within
scope will only look at the first element that matches. We find this behavior to be impractical, but it is by design.
In order to perform a test or action in all matching elements, do not use within
but prefer the attached "inside any
" Cucumber steps like these:
When I follow "Foo" inside any "table"
Then I should see "Bar" inside any "li"
How to fix broken font collisions in wkhtmltopdf
If you are using PDFKit / wkhtmltopdf, you might as well want to use custom fonts in your stylesheets. Usually this should not be a problem, but at times they include misleading Meta-information that leads to a strange error in the PDF.
The setup
- The designer gave you two fonts named something like
BrandonText-Regular
andBrandonText-Bold
. (With flawed Meta-information) - You have a HTML string to be rendered by PDFKit
- For demonstration purposes, this strin...
How to add a custom dictionary to Ruby Mine
- Download the dictionary from http://www.winedt.org/dict.html, e.g.
http://www.winedt.org/dict/de_neu.zip
unzip de_neu.zip
mkdir ~/Documents/dic
iconv -f UTF-16 -t UTF-8 de_neu.dic -o ~/Documents/dic/de_neu_utf8.dic
- In RubyMine: Go to Settings (CTRL + ALT + S) > Editor > Spelling > Dictionaries and add the folder
~/Documents/dic
How to move all files in a folder to a new subfolder
Let's say you have a folder images
and want to to move all files in there to a new subfolder public
.
cd images
mkdir public
mv !(public) public
The !(public)
excludes the new subfolder itself from being moved.
How to exploit websites that include user input in their CSS
The linked article shows how to exploit websites that include unsanitized user input in their CSS.
Although the article often mentions React and CSS-in-JS libraries, the methods are applicable to any web app that injects user input into style
tags or properties.
Also, sanitizing user input for CSS injection is much harder than sanitizing HTML.
A Theme Switcher
Hack to implement an inverted "night mode" theme with a few lines of CSS.
Colors in images are preserved.
Bundler 2 will rename Gemfile and Gemfile.lock
TL;DR: Bundler 2.0 will rename Gemfile
to gems.rb
and Gemfile.lock
to gems.locked
(sic).
The old filenames will be supported until the release of Bundler 3.0.
Association to polymorphic model does not determine inverse_of automatically
You need to set the :inverse_of
option manually for relations that have an association to a polymorphic model. Otherwise you will not be able to save a record with a nested polymorphic association.
class Event < ApplicationRecord
has_many :letters, as: :record
end
class Letter < ApplicationRecord
belongs_to :record, polymorphic: true
end
event = Event.new.letters.build
event.save! # => ActiveRe...
How to enable the Thinkpad microphone mute key on Ubuntu 16.04
While the hardware mute button of my Lenovo x230 worked on Ubuntu 14.04 out of the box, it does not on Ubuntu 16.04. It is fairly simple to fix, though.
There is an extensive answer on Ask Ubuntu, but only part of it was required for me. Here is the gist of it.
-
Open a terminal
-
Run
acpi_listen
and press the mute key. You should see something like this:button/f20 F20 00000080 00000000 K
Press
Ctrl
+C
to exit. -
Run
amixer scontrols
. You will see multiple lines, one of which sh...
Rails: render a template that accepts a block by using the layout option of render
Let's say you have a form that you render a few times but you would like to customize your submit section each time. You can achieve this by rendering your form partial as layout and passing in a block. Your template or partial then serves as the surrounding layout of the block that you pass in. You can then yield back the form to the block and access the form in your block.
-# record/_form.haml
= form_for record do |form|
-# ...
.form-actions
yield(form)
In order to make your template record/_form.haml
accept a...
How to change the class in FactoryBot traits
FactoryBot allows a :class
option to its factory
definitions, to set the class to construct. However, this option is not supported for trait
s.
Most often, you can just define a nested factory instead of a trait, and use the :class
option there.
factory :message do
factory :reply, class: Message::Reply do
# ...
end
end
If you need/want to use traits instead (for example, it might make more sense semantically), you can not use a :class
on a trait
.
In that case, use initialize_with
to define the record's constr...
Import Excel files without running into memory limitations
There are several gems that make it easy to read and process xlsx files. Parsing the entire file at once however is error-prone since each cell is transformed to a ruby object - sometimes including thousands of formatted but empty cells.
As of today, I found two promising alternatives that provide a stream-based access to spradsheet rows:
- Roo supports multiple spreadsheet types like ODS or CSV and has a quite large contributor base
- [Creek](https://github.com/pythonicrubyis...
Ubuntu MATE: Fixing ALT + TAB being really slow
On my Ubuntu MATE machine, switching applications with ALT + TAB was impossible, because it took nearly 2 seconds. The culprit appears to be an "UX improvement" gone bad: MATE renders a live screenshot of each running application inside the application switcher.
Fixing this is simple:
- Open "Window Preferences"
- Either uncheck "Enable software compositing window manager" or check "Disable thumbnails in Alt-Tab"
Sentry: How to get a list of events that is programmatically processable
The linked documentation explains how to get a JSON list of the latest 100 events of a given issue. Simply open this URL while logged in:
https://sentry.io/api/0/issues/<issue id>/events/
Postgres: How to force database sessions to terminate
If another session is accessing your database you are trying to reset or drop you might have seen the following error:
PG::ObjectInUse: ERROR: database "foo_development" is being accessed by other users
DETAIL: There is 1 other session using the database.
This could be the rails server, rubymine and many more. Beside terminating the session connection manually you can also find out the pid
and kill the process.
1. rails db
2. SELECT * FROM pg_stat_activity;
datid | 98359
datname | foo_developm...
How to pair a Bose Quiet Comfort 35 with your Ubuntu computer
You need to disable "Bluetooth low energy", then follow these core steps:
- Make sure the headphones are in pairing mode.
- Pair with System Settings > Bluetooth. On 16.04 I had to choose "proceed without pairing" and enter the PIN "0000"
- Select & test the headphones in System Settings > Sound. Choose High Fidelity Playback (A2DP Sink).
I also had to install a package with sudo apt-get install pulseaudio-module-bluetooth
and load it with pactl load-module module-bluetooth-discover
. Put the latter command into ~/.bashrc
or you'll...
JavaScript bookmarklet to click an element and copy its text contents
Here is some JavaScript code that allows you to click the screen and get the clicked element's text contents (or value, in case of inputs).
The approach is simple: we place an overlay so you don't really click the target element. When you click the overlay, we look up the element underneath it and show its text in a browser dialog. You can then copy it from there.
While moving the mouse, the detected element is highlighted.
Here is the one-liner URL that you can store as a bookmark. Place it in your bookmarks bar and click it to activate....
Custom Ruby method Enumerable#count_by (use for quick statistics)
I frequently find myself needing a combination of group_by
, count
and sort
for quick statistics. Here's a method on Enumerable
that combines the three:
module Enumerable
def count_by(&block)
list = group_by(&block)
.map { |key, items| [key, items.count] }
.sort_by(&:last)
Hash[list]
end
end
# Returns a Hash of { key => count } pairs (see below)
Just paste that snippet into a Rails console and use #count_by
now!
Usage examples
- Number of email addresses by domain:
> User.all.co...
Async/Await Will Make Your Code Simpler
Sometimes modern Javascript projects get out of hand. A major culprit in this can be the messy handling of asynchronous tasks, leading to long, complex, and deeply nested blocks of code. Javascript now provides a new syntax for handling these operations, and it can turn even the most convoluted asynchronous operations into concise and highly readable code.
JavaScript: How to query the state of a Promise
Native promises have no methods to inspect their state.
You can use the promiseState
function below to check whether a promise is fulfilled, rejected or still pending:
promiseState(promise, function(state) {
// `state` now either "pending", "fulfilled" or "rejected"
});
Note that the callback passed to promiseState
will be called asynchronously in the next [microtask](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/...
Vagrant: create entry for box in .ssh/config
If you want to ssh into your vagrant box without switching into the project directory and typing vagrant ssh
, you can also create an entry directly in ~/.ssh/config
. This will allow you to use ssh <my-box>
from anywhere. Simply paste the information provided by vagrant ssh-config
to your ~/.ssh/config
-File: vagrant ssh-config >> ~/.ssh/config
Example:
$ vagrant ssh-config
Host foobar-dev
HostName 127.0.0.1
User vagrant
Port 2200
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
Id...
How to install a current version of git to your Ubuntu machine
As described by the linked Stackoverflow answer, run these commands:
sudo add-apt-repository ppa:git-core/ppa -y
sudo apt-get update
sudo apt-get install git
git --version
This will get you Git 2.6.4 (as of Dec 2015).
Troubleshooting
If you don't have add-apt-repository
yet, install it with:
sudo apt-get install python-software-properties software-properties-common
Understanding Scope in Ruby
Scope is all about where something is visible. It’s all about what (variables, constants, methods) is available to you at a given moment. If you understand scope well enough, you should be able to point at any line of your Ruby program and tell which variables are available in that context, and more importantly, which ones are not.
The article gives detailed explanation on the variable scope in ruby with examples that are easy to understand. Every ruby developer should at least know the first part of the article by heart. The second half ...