When using "render :text", set a content type

When your Rails controller action responds with only a simple text, render text: 'Hello' may not be what you want. You should not even use it on Rails 4.1+ any more.

By default, a "text" response from a Rails controller will still be a sent as text/html:

render text: 'Hello'
response.body # => "Hello"
response.content_type # => "text/html"

While this may not be too relevant for a Browser client, the response's content type is simply wrong if you want to send a plain-text response, and can cause trouble. \
For example, con...

OpenStack nova resize "ERROR: Resize requires a change in size"

If you get this error when you try to resize an OpenStack instance:

# nova resize example 23 --poll
ERROR: Resize requires a change in size. (HTTP 400)

You need to change your flavor to have a different memory size. It's a bug in an older OpenStack version:

        # /nova/compute/api.py
        if (current_memory_mb == new_memory_mb) and flavor_id:		
            raise exception.CannotResizeToSameSize()

which got fixed 2012-09-12 ([https://git.openstack.org/cgit/openstack/nova/commit/nova/compute/api.p...

Bash output redirection

There are 3 built-in file descriptors: stdin, stdout and stderr (std=standard). (You can define your own, see the linked article.)

Basic

  • 0/1/2 references stdin/stdout/stderr
  • >/2> redirects stdout/stderr, where > is taken as 1>
  • &1/&2 references stdout/stderr
  • &> redirects stdout and stderr = everything (caution: see below)

Caution: &> is functional as of Bash 4. This seems to result in a slightly differing behaviour when redirecting output in Ru...

Strong params: Raise in development if unpermitted params are found

Rails 4:

config.action_controller.action_on_unpermitted_parameters enables logging or raising an exception if parameters that are not explicitly permitted are found. Set to :log or :raise to enable. The default value is :log in development and test environments, and false in all other environments.

Rails 3:

If you include the strong_params gem, see the Readme for handling unpermitted keys.

Disabling Spring when debugging

Spring is a Rails application preloader. When debugging e.g. the rails gem, you'll be wondering why your raise, puts or debugger debugging statements have no effect. That's because Spring preloads and caches your application once and all consecutive calls to it will not see any changes in your debugged gem.

Howto

Disable spring with export DISABLE_SPRING=1 in your terminal. That will keep Spring at bay in that terminal session.

In Ruby, [you can only write environment variables that subproc...

How to create Rails Generators (Rails 3 and above)

General

Programatically invoke Rails generators

Require the generator, instantiate it and invoke it (because generators are Thor::Groups, you need to invoke them with invoke_all). Example:

 require 'generators/wheelie/haml/haml_generator'
 Generators::HamlGenerator.new('argument').invoke_all

Other ways: Rails invokes its generators with Rails::Generators.invoke ARGV.shift, ARGV. From inside a Rails generator, you may call the [inherited Thor method invoke(args=[], options={}, config={})](https://github...

docopt: A promising command line parser for (m)any language

docopt helps you define interface for your command-line app, and automatically generate parser for it.

docopt is based on conventions that are used for decades in help messages and man pages for program interface description. Interface description in docopt is such a help message, but formalized. Here is an example:

Naval Fate.

Usage:
  naval_fate ship new <name>...
  naval_fate ship <name> move <x> <y> [--speed=<kn>]
  naval_fate ship shoot <x> <y>
  naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
  naval_fate -h |...

Restangular: How to remove an element from a collection without breaking restangular

So you have a restangular collection and you want to remove an element from it, after you've successfully deleted it from the server.

The README suggests to say something like $scope.users = _.without($scope.users, user). While that works at first glance (the element is no longer in your collection), it will break horribly when you want to use restangular's attributes on that collection.

This...

better rails app restart with the passenger restart-app tool

With this command you can initiate an application restart without touching restart.txt. Unlike touching restart.txt, this tool initiates the restart immediately instead of on the next request. http://blog.phusion.nl/2014/01/02/phusion-passenger-4-0-33-released/

If you want to use this with capistrano 2.x just replace the touch command:

-    run "touch #{current_path}/tmp/restart.txt"
+    run "passenger-config restart-app --ignore-app-not-running #{deploy_to}...

Linux: How to print PDF files from the command line

Sometimes you may want to print files from the command line, especially when you have lots of them.
You can use lp for that.

To print a single example.pdf file on your default printer, simply say:

lp example.pdf

lp accepts multiple filenames, so to print all PDF files in the current directory:

lp *.pdf

You can specify a printer via the -d switch:

lp -d YOUR_PRINTER_NAME *.pdf

Your printer's name is then one you defined on your system. You can check with your CUPS configuration by visiting `http://localhost:631/...

Test whether Perfect Forward Secrecy (PFS) is enabled on a server (using OpenSSL)

Use the following command to test if a server (in this example: makandra.com on port 443) uses Perfect Forward Secrecy (PFS):

openssl s_client -connect makandra.com:443 -cipher ECDHE-RSA-RC4-SHA

You should see something like the following:

~ > openssl s_client -connect projecthero.com:443 -cipher ECDHE-RSA-RC4-SHA
CONNECTED(00000003)
depth=1 O = AlphaSSL, CN = AlphaSSL CA - G2
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=DE/OU=Domain Control Va...

Heartbleed test

Enter the hostname of a server to test it for CVE-2014-0160.

No more file type confusion in TextMate2

When using TextMate2 with the cucumber bundle, it does not recognize step definitions (e.g. custom_steps.rb) as such but believes they are plain Ruby files. But there is help!

Solution

Add these lines to the bottom of your .tm_properties file (in ~/ for global settings, in any directory for per-project settings):

[ "*_steps.rb" ]
fileType = "source.ruby.rspec.cucumber.steps"

Apparently, this works for any files. Define a regex and specify custom settings. The attached article lists all available configuration options (whic...

BrowserStack has browser plugins for local testing

Local testing allows you to test your private and internal servers using the BrowserStack cloud, which has support for firewalls, proxies and Active Directory.

How to simulate limited bandwidth in Google Chrome and Firefox

Your development machine is usually on a very good network connection.
To test how your application behaves on a slow network (e.g. mobile), you can simulate limited bandwidth.

Chrome

  • Open the dev tools (Ctrl+Shift+I or F12) and switch to the "Network" tab
  • In the row below the dev tool tabs, there's a throttling dropdown which reads "Online" by default.
  • Inside the dropdown, you will find a few presets and an option to add your own download/upload/latency settings.

Firefox

  • Open the dev tools (Ctrl+Shift+I or F12) and switc...

JavaScript: How to log execution times to your browser console

If you are trying to inspect timings in JavaScript, you can use console.time and console.timeEnd which will write to your browser console.

Example:

console.time('lengthy calculation');
lengthyCalculation();
console.timeEnd('lengthy calculation');

lengthy calculation: 1.337ms

Note that this allows using console.timeEnd in another context which is helpful when you are doing things asynchronously, or just in different places.

Works in all browsers, including recent Internet Explorers. For older IEs, you may activate...

How Ruby method lookup works

When you call a method on an object, Ruby looks for the implementation of that method. It looks in the following places and uses the first implementation it finds:

  1. Methods from the object's singleton class (an unnamed class that only exists for that object)
  2. Methods from prepended modules (Ruby 2.0+ feature)
  3. Methods from the object's class
  4. Methods from included modules
  5. Methods from the class hierarchy (superclass and its an...

Why belongs_to/has_many cannot overwrite methods with the same name

When you use a belongs_to or has_many macro you might be surprised that the methods that it generates does not override a method with the same name. Take this example:

class Project < ActiveRecord::Base
  
  def user
    "foo"
  end
  
  belongs_to :user
  
end

Project.new.user still returns "foo".

The reason for this is that what belongs_to does is actually this:

class Project < ActiveRecord::Base
  include FeatureMethods
  
  def user
    "foo"
  end
  
end

module Project::FeatureMethods

  def user
    # ass...

Collection of Rails development boosting frameworks

Development environment setup

Rails Composer

Basically a comprehensive Rails Template. Prepares your development environment and lets you select web server, template engine, unit and integration testing frameworks and more.

Generate an app in minutes using an application template. With all the options you want!

Code generators

Rails Bricks

A command line wizard. Once you get it running, it creates sleek applications.

RailsBricks enables you to cre...

Cucumber does not find neither env.rb nor step definitions when running features in nested directories

Usually, Cucumber feature files live in features/. When you group them in sub directories, make sure to add -r features to the standard Cucumber options.

In Rails apps, Cucumber options are likely to be stored in config/cucumber.yml.

Don't build randomness into your factories

Tests are about 100% control over UI interaction and your test scenario. Randomness makes writing tests hard. You will also push tests that are green for you today, but red for a colleague tomorrow.

That said, please don't do something like this:

Factory(:document) do |document|
  document.category { ['foo', 'bar', 'baz'].sample }
end

Instead do this:

Factory(:document) do |document|
  document.category 'foo'
end

The case against Faker

I even recommend to not use libraries like [Faker]...

Cucumber: Wait until CKEditor is loaded

I had to deal with JavaScript Undefined Error while accessing a specific CKEditor instance to fill in text.

Ensure everything is loaded with

patiently do
  page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
end

Example

The fill in text snippet for Cucumber:

When /^I fill in the "([^\"]+)" WYSIWYG editor with:$/ do |selector, html|
  patiently do
    page.execute_script("return isCkeditorLoaded('#{selector}');").should be_true
  end
  html.gsub!(/\n+/, "") # otherwise: unterminated string lit...

Namespacing: why `uninitialized constant` error may occour in `development` but not in `test` environment

Example:

  class Book::Page
  end
  
  class MyBook < Book
    def new_page
      Page.new # has to be `Book::Page` in development to make it work 
    end
  end

Method new_page may throw an error when it was called during browser interaction in development but doesn't make the test fail.

The reason

Development autoloading isn't smart enough to find the referenced class
At other environments (test, staging, production) autoloading is disabled, that all classes are already loaded when browser interaction takes place what makes...

Howto prompt before accidentally discarding unsaved changes with JavaScript

Ask before leaving an unsaved CKEditor

Vanilla JavaScript way, but removes any other onbeforeunload handlers:

  $(function(){
    document.body.onbeforeunload = function() {
      for(editorName in CKEDITOR.instances) {
        if (CKEDITOR.instances[editorName].checkDirty()) {
          return "Unsaved changes present!"
        }
      }
    }
  }

A robuster implementation example

Note: Don't forget to mark the 'search as you type' forms with the skip_pending_changes_warning class.

var WarnBeforeAccidentallyDiscard...