Change the existing order of an ActiveRecord scope

Use reorder to replace an existing order clause with a new expression.

The Curious Case of the Flip-Flop

The flip-flop operator is a hotly contested feature of Ruby. It's still struggling to find an idiomatic use case, except for a few very rarely needed things. It's not something you'll likely reach for on a daily, weekly or even monthly basis. The only thing you really need to know about it is what it does, and that's only in case you encounter it in someone else's code. Many even go as far to say not to use the flip-flop operator, that it only adds confusion.

My brain just melted.

Using rbenv on Ubuntu 18.04+

We will be installing rbenv and ruby-build from our own fork, not from the Ubuntu sources.

Installing rbenv

  1. Install rbenv:

    git clone https://github.com/rbenv/rbenv.git ~/.rbenv
    

    For Bash:

    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
    echo 'eval "$(rbenv init -)"' >> ~/.bashrc
    

    For ZSH:

    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
    echo 'eval "$(rbenv init -)"' >> ~/.zshrc
    

    Now reinitialize ...

Perform Sidekiq jobs immediately in development

# config/initializers/sidekiq.rb

# Perform Sidekiq jobs immediately in development,
# so you don't have to run a separate process.
# You'll also benefit from code reloading.
if Rails.env.development?
  require 'sidekiq/testing'
  Sidekiq::Testing.inline!
end

RSpec example groups can be named using symbols

Though nowhere to be found in the official docs, this works just fine.

describe Facebook::Post do
  it_behaves_like :time_series
end

shared_examples_for :time_series do
  # shared example code
end

Using the Facebook Graph API

App tokens

For server-to-server requests to the Facebook Graph API you can skip requesting an Oauth token, an instead use the combination of app_id|app_secret as your access token. This token will never expire, and should suffice for retrieving basic information from the Graph API.

http://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret

Since you don't make requests for a certain user, the Graph API might respond with an error in case you're requesting a resource that requires authenticating as a human...

Upgrade to LibreOffice 5.x on Ubuntu

Getting rid of your old LibreOffice

Remove your old LibreOffice:

sudo apt-get remove libreoffice*

You probably also want to get rid of the dead PPAs you might have installed for LibreOffice 4.x:

  • Open *Ubuntu Software Center
  • Go to Edit / Software Source ... / Other Software
  • Find and uncheck lines like http://ppa.launchpad.net/libreoffice/libreoffice-4-3/ubuntu. Note that you will probably have at least two lines pertaining to libreoffice.

Installing a new LibreOffice
-------------...

Git: Diff per word or character

By default git diff highlights whole lines as changes.

To diff on a word-by-word basis you can say:

git diff --color-words

To diff on a character-by-character basis you can say:

git diff --color-words=.

Ubuntu: Fix "An error occurred while installing pg"

If you get an error like this:

An error occurred while installing pg (0.17.1), and Bundler cannot continue.
Make sure that gem install pg -v '0.17.1' succeeds before bundling.

Then do this:

sudo apt-get install libpq-dev

... and run Bundler again.

Paperdragon: Explicit Image Processing

It's like Paperclip or CarrierWave, but without any automagic integration.

Openstack: Create a Flavor

List flavors to show the ID and name, the amount of memory, the amount of disk space for the root partition and for the ephemeral partition, the swap, and the number of virtual CPUs for each flavor.

$ nova flavor-list

To create a flavor, specify a name, ID, RAM size, disk size, and the number of VCPUs for the flavor, as follows:

$ nova flavor-create FLAVOR_NAME FLAVOR_ID RAM_IN_MB ROOT_DISK_IN_GB NUMBER_OF_VCPUS

The ID of the new flavor should always be one higher than the highest.

Why Most Freelancers Set Their Clients Up For Failure (And How To Fix This)

How you can unknowingly screw your client's business when all you think about is closing the next user story.

Rails routes: Extracting collection actions into their own controllers

Let's say you have two screens:

  1. Show a given project
  2. Show a report for all projects

Ideally you want both screens to be handled by different controllers like this:

GET /projects/:id        => ProjectsController#show
GET /projects/report     => Projects::ReportsController#show

What seems like a simple requirement is a little awkward to configure in your routes.
Obviously the report should be a singleton resource, but how can we nest it into the Projects:: namespace?

What does not work is this:

resources :proj...

Rspec: Complex argument expectations for should_receive

Sometimes you need complex expectations on method arguments like this

SomeApi.should_receive(:find).with(:query => '*foo*', :sort => 'timestamp ASC', :limit => 100).and_return(['some result'])

This is not very flexible, and failure messages will be hard to read.

Instead, consider doing this:

SomeApi.should_receive(:find) do |params|
  params[:query].should == '*foo*'
  params[:sort].should == 'timestamp ASC'
  params[:limit].should == 100
  
  ['some result']
end

What we know about PDFKit

What PDFKit is

  • PDFKit converts a web page to a PDF document. It uses a Webkit engine under the hood.
  • For you as a web developer this means you can keep using the technology you are familar with and don't need to learn LaTeX. All you need is a pretty print-stylesheet.

How to use it from your Rails application

  • You can have PDFKit render a website by simply calling PDFKit.new('http://google.com').to_file('google.pdf'). You can then send the...

Complexity in Software 3: The Constructal Law

Talks about some basics of software complexity. Very nice illustrations.

JavaScript: Moving elements inside an array, modifying the array in place

If you want to move an element inside an array, neither JavaScript/ES6+ nor libraries like LoDash offet that natively.

Here is a simple function instead that modifies the input array in place.

function moveArrayElement(array, element, offset) {
  const index = array.indexOf(element)
  const newIndex = index + offset
  
  if (newIndex > -1 && newIndex < array.length) {
    // Remove the element from the array
    const removedElement = array.splice(index, 1)[0]

    // At "newIndex", remove 0 elements and insert the removed el...

Testing drag&drop with Selenium

When using jQueryUI's Sortable plugin (either directly or via Angular's ui.sortable), you might struggle testing your nice drag&drop GUI since Selenium webdriver does not support native dragging events.

But jQueryUI uses jquery.simulate for their testing, so why shouldn't you? There is even an extension to it that makes testing drag & drop quite easy.

Here is what you need:

  1. jquery.simulate.js
  2. [`jquery.simula...

Linux: Get your public IP address from the shell

curl http://ipecho.net/plain; echo

Transactional HTML Email Templates

Styling HTML email is painful. Tables, inline CSS, unsupported CSS, desktop clients, web clients, mobile clients, various devices, various providers. All these things have to be thought about and tested. It’s no surprise developers don’t want to deal with this when there is a backlog of more important priorities.

We’ve tried to remove some of the pain for you and open-sourced a collection of common templates for transactional email.

Alternative transactional email templates include

  • [these ones...](https://www.sendwithus.com/resource...

Rails 3: Mass assignment protection and .create_with

The issue

Yesterday, Rails fixed a security issue (CVE-2014-3514) in Rails 4+. It was possible to use .where or .create_with to bypass Rails' Strong Parameters:

user.blog_posts.create_with(params[:blog_post]).create

would set all attributes on the blog post. After the fix, you have to properly whitelist the params, via `params[:blog_post].permit(:title, :bo...

jQuery: Work with text nodes and comment nodes

Nearly all jQuery traversal functions ignore elements that are not HTML tags.

To work with other type of nodes (like text, comment or CDATA sections) you need to:

  • Retrieve child nodes contents() (which behaves like children() except that it returns all types of child nodes)
  • Filter manually using either plain Javascript or jQuery's filter() method

Example

Let's write a function that takes a jQuery element and returns an array of all child nodes that are text nodes:

function selectTextNodes($container) {
  retu...

Vastly increase the usability of Thunderbird's search

These two addons will change your life:

Search as list

This will always open search results in the list views instead of the barely usabely faceted search view.

Sort search results by date not relevance

Does what it says.

Mind blown

Interacting with a Microsoft Exchange server from Ruby

Microsoft Exchange service administrators can enable Exchange Web Services (EWS) which is a rather accessible XML API for interacting with Exchange. This allows you to read and send e-mails, create appointments, invite meeting attendees, track responses, manage to-do tasks, check user availability and all other sorts of things that are usually only accessible from Outlook.

You can implement an EWS by hand-rolling your XML (the [docs](http://msdn.microsoft.com/en-us/...