ActiveRecord subselects - Today I Learned

Apparently you can pash a second scope to a hash-condition and the whole thing will be evaluated as a second SELECT statement with a subselect.

Note that sub-queries are extremely slow in MySQL, but they can make cases easier where performance does not matter so much (e.g. a migration on 50K records).

has_one association may silently drop associated record when it is invalid

This is quite an edge case, and appears like a bug in Rails (4.2.6) to me.

Update: This is now documented on Edgeguides Ruby on Rails:

If you set the :validate option to true, then associated objects will be validated whenever you save this object. By default, this is false: associated objects will not be validated when this object is saved.

Setup

# post.rb
class Post < ActiveRecord::Base
  has_one :attachment
end
# attachm...

Download Ruby gems without installing

You can download .gem files using gem fetch:

gem fetch activesupport consul

This will produce files like active-support-5.0.0.gem and consul-0.12.1.gem in your working directory.

Dependencies will not be downloaded.

Linux: Find out which processes are swapped out

Processes in Linux might be put into Swap ("virtual memory") occasionally.
Even parts of a single process might be removed from memory and put into Swap.

In order to find out which processes remain within Swap, run this:

sudo grep VmSwap /proc/*/status | egrep -v "0 kB"

Keep in mind Swap is not evil by definition. Some bytes per process beeing put to Swap will not have that much of performance influence.

If you want the Linux virtual memory manager (which is responsible for the decision if and which processes are moved to Swap) to be...

Tasks, microtasks, queues and schedules - JakeArchibald.com

The way that Javascript schedules timeouts and promise callbacks is more complicated than you think. This can be the reason why callbacks are not executed in the order that they are queued.

Please read this article!


This is an extract of the example in the article which demonstrates the execution order of tasks and microtasks.

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
})...

Rails Env Widget

Have you ever mistaken one Rails environment for another? The attached helper will help you to never do it again.

Save the attached file to app/helpers/ and use the widget in your layout like this:

%body
  = rails_env_widget unless Rails.env.production?

It'll render a small light gray box in the top left corner of your screen, containing the current Rails environment. On click, it'll disappear. Actually, it has the same UX as our Query Diet widget.

Dynamically uploading files to Rails with jQuery File Upload

Say we want …

  • to create a Gallery that has a name and has_many :images, which in turn have a caption
  • to offer the user a single form to create a gallery with any number of images
  • immediate uploads with a progress bar per image
  • a snappy UI

Enter jQuery File Upload. It's a mature library that can do the job frontend-wise. On the server, we'll use Carrierwave, because it's capable of caching images.

(FYI, [here's how to do the u...

UI Sortable on table rows with dynamic height

UI sortable helps reordering items with drag 'n drop. It works quite fine.

Proven configuration for sorting table rows

When invoking the plugin, you may pass several options. This set is working fine with table rows:

$tbody.sortable # Invoke on TBODY when ordering tables
  axis: 'y' # Restrict drag direction to "vertically"
  cancel: 'tr:first-child:last-child, input' # Disable sorting a single tr to prevent jumpy table headers
  containment: 'parent' # Only drag within this container
  placehol...

Javascript: Wait until an image has finished loading

The attached ImageLoader helper will start fetching an image and return an image that is resolved once the image is loaded:

ImageLoader.load('/my/image.png').then(function(image) {
  ...
});

The image argument that is yielded to the promise callback is an HTMLImageElement. This is the kind of object you get when you call new Image().

How to fix: "rake db:rollback" does not work

When you run rake db:rollback and nothing happens, you are probably missing the latest migration file (or have not migrated yet).

$ rake db:rollback
$ 

If that happens to you, check your migration status.

$ rake db:migrate:status
   up     20160503143434  Create users
   up     20160506134137  Create pages
   up     20160517112656  Migrate pages to page versions
   up     20160518112023  ********** NO FILE **********

When you tell Rails to roll back, it tries to roll back the latest change that was mi...

postgres_ext: additional Rails bindings for PostgreSQL

Adds missing native PostgreSQL data types to ActiveRecord and convenient querying extensions for ActiveRecord and Arel for Rails 4.x

Common table expressions

  • Relation#with
  • Model.from_cte

Arrays

Face.where.contains tags: %w[happy smiling] # Matching faces have both 'happy' and 'smiling' tags
Face.where.overlap tags: %w[happy smiling] # Matching faces have at least one of these tags
Face.where.any tags: 'happy' # Matching faces include the 'happy' tag
Face.where.all tags: 'dunno' # Not documented, try for yourself

...

How to explain SQL statements via ActiveRecord

ActiveRecord offers an explain method similar to using EXPLAIN SQL statements on the database.

However, this approach will explain all queries for the given scope which may include joins or includes.

Output will resemble your database's EXPLAIN style. For example, it looks like this on MySQL:

User.where(id: 1).includes(:articles).explain
EXPLAIN for: SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1
+----+-------------+-------+-------+---------------+
| id | select_type | table | type  | possible_keys |
+----+-----...

Introducing Helix: Rust + Ruby, Without The Glue

Helix allows you to implement performance-critical code of your Ruby app in Rust, without requiring glue code to bridge between both languages.

See attached article for a longer write-up about the why and how.

rroblak/seed_dump

This gem gives you a rake task db:seed:dump do create a db/seeds.rb from your current database state.

The generated db/seeds.rb will look this:

Product.create!([
  { category_id: 1, description: "Long Sleeve Shirt", name: "Long Sleeve Shirt" },
  { category_id: 3, description: "Plain White Tee Shirt", name: "Plain T-Shirt" }
])
User.create!([
  { password: "123456", username: "test_1" },
  { password: "234567", username: "test_2" }
])

Install MySQL 5.6 in Ubuntu 16.04

Instead of using this hack you might want to use MariaDB 10.x which can work with both old and new apps.


An alternative could be to use the MySQL Docker image which is still updated for 5.6.


Ubuntu 16.04 only provides packages for MySQL 5.7 which has a range of backwards compatibility issues with code written against older MySQL versions.

Oracle maintains a list of official APT repositories for MySQL 5.6, but those repositories do...

VCR: An OAuth-compatible request matcher

OAuth requires a set of params to be carried along requests, among which a nonce. Some libraries pass these along as headers, some as query parameters. All fine.

When you're using VCR, the latter case is an issue. By default, requests are matched on method and URI. However, no request URI will equal another when they include a nonce. You won't be able to match these requests with VCR.

Solution

Obviously you need to...

Postgres Index Types

When creating an index using CREATE INDEX, Postgres will create a B-Tree type index by default. The B-Tree type is great for general purpose indexes but there are special cases when other types provide better results.

jQuery promises: done() and then() are not the same

jQuery's deferred objects behave somewhat like standard promises, but not really.

One of many subtle differences is that there are two ways to chain callbacks to an async functions.

The first one is done, which only exists in jQuery:

$.ajax('/foo').done(function(html) {
  console.debug("The server responded with %s", html);
});

There is also then, which all promise libraries have:

$.ajax('/foo').then(function(html) {
  console.debug("The server resp...

MySQL / MariaDB: Show disk usage of tables and columns

You can find out about disk space usage of all tables within your database by running this:

SELECT table_name AS `Table`, round(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` FROM information_schema.TABLES WHERE table_schema = "$your_database";

Replace $your_database here.

To find out the disk usage of a single column:

SELECT sum(char_length($your_column))/1024/1024 FROM $your_table

Result is in megabytes again.

Stackprof - sampling call-stack profiler for ruby

Stackprof is a sampling call-stack profile for Ruby 2.1+.

Instead of tracking all method calls, it will simply collect the current stack trace of a running program at fixed intervals. Methods that appear on top of the stack trace most often, are the methods your program spends most of its time in.

The big advantage of this is that it is very fast. You can even enable it in production and collect real performance data. See the README on how to add it as a middleware. It will dump its data to the tmp directory.

Sampling is by default base...

Linux: Open a file with the default application

If you are on a Linux shell and want to open a file with whatever default application is configured for that type, this often works:

xdg-open Quote.odt
xdg-open invoice.pdf
xdg-open index.html

Pro Tip

Make an alias so you have a simpler API (like Mac OS): alias open=xdg-open or alias x=xdg-open.

Background

You can choose your "Default applications" via UI in the Ubuntu "Settings" application (gnome-control-center). This is just a very rough setting (e.g. open Photos with Shotwell Viewer).

If a certain file...

Testing ActiveRecord callbacks with RSpec

Our preferred way of testing ActiveRecord is to simply create/update/destroy the record and then check if the expected behavior has happened.

We used to bend over backwards to avoid touching the database for this. For this we used a lot of stubbing and tricks like it_should_run_callbacks.

Today we would rather make a few database queries than have a fragile test full of stubs.

Example

Let's say your User model creates a first Project on cr...

Testing ActiveRecord validations with RSpec

Validations should be covered by a model's spec.

This card shows how to test an individual validation. This is preferrable to save an entire record and see whether it is invalid.

Recipe for testing any validation

In general any validation test for an attribute :attribute_being_tested looks like this:

  1. Make a model instance (named record below)
  2. Run validations by saying record.validate
  3. Check if record.errors[:attribute_being_tested] contains the expected validation error
  4. Put the attribute into a valid state
  5. Run...

record a logstalgia video

Cause logstaglia is so cool you may want to record a video. We're lucky: Logstalgia has a parameter for an ppm-stream output: --output-ppm-stream FILE. We can pipe this to ffmpeg or avconv to record a h264 encoded video.

record command when using ffmpeg (for e.g. with ubuntu 12.04)

cat some_acces.log | logstalgia --sync -1920x1080 --output-ppm-stream - | ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 logstalgia.mp4

record command when using avconv(...