View
Repeats

Execution of shell code in Ruby scripts

There are countless ways to execute shell code in Ruby. You should always use capture3, for which we have a dedicated card because it is so good.

All other methods to execute shell commands have signficant downsides, such as:

  • They do not tell you if the command has succeeded
  • They only return STDOUT, but not STDERR with error messages
  • They don't let you choose whether command output appears on the screen or not
  • They allow to inject code that will be interpreted by the shell
  • You alway…

Shoulda Matchers: how to test conditional validations

Shoulda Matchers don't provide canditional validations (validations with if: option). Here is how to write tests for the condition:

Class:

class Employee < ActiveRecored::Base
  validates :office, presence: true, if: manager?
  
  def manager?
    ...
  end
end

Test:

```ruby
describe Employee do

describe '#office' do

context 'is a manager' do
  before { allow(subject).to receive(:manager?).and_return(true) }
  it { is_expected.to validate_presence_o...

PostgreSQL: How to add/remove/modify array values (and how to replace 1 value with multiple values)

PostgreSQL's array data type is pretty useful, but manipulating values of arrays can be awkward because of its syntax.

Consider the following users table which each example below will start from:

name topics
Alice {cats,dogs}
Bob {llamas}

(PostgreSQL uses curly braces to represent arrays, true story.)

Adding values

Use the array_cat function, or the || operator.

These calls will add the values "cats" and "mice" to user…

Repeats

Rails: how to write custom email interceptors

Nowadays it is fairly easy to intercept and modify mails globally before they are sent. All you have to do is register an interceptor class which responds to .delivering_email(message). This card will show you two common use cases.

Subject prefix:

Usually you want to prefix the subject line of emails with the current environment (except production) so you can differentiate between production mails and mails from other environments. Of course a prefix can be set directly in the mailer, however, it is safer and cleaner to d…

Repeats

How to bulk-unwatch many repositories on Github

To easily opt out of notifications for a large number of Github repositories, go to https://github.com/watching.

Repeats

Minified JavaScript and CSS

JavaScripts and CSS should be minified for production use.

In Rails 3.1+ the asset pipeline will take care of this. Thus you're best off using an uncompressed version of your Javascript in development. Also load the non-minified versions of libraries. This way debugging will be easier and you will still get all the minification love once deployed.

In Rails 2.3 and 3.0 you should at least embed external JavaScript libraries in minified form, using something like JavaScript compressor.

Howto: Rails cache for individual rspec tests

Rails default config uses the ActiveSupport::Cache::NullStore and disables controller caching for all environments except production:

config.action_controller.perform_caching = false
config.cache_store = :null_store

If you want to test caching you have at least two possibilities:

  1. Enable caching for every test (not covered by this card and straightforward)
  2. Enable caching for individual test

Enable caching for individual test (file cache)

1. Leave the default c…

External content

RawGit

RawGit serves raw files directly from GitHub with proper Content-Type headers, for CDN-like purposes.

Note that they don't offer any uptime guarantee. You probably don't want to use it in production, but it may serve you well for some testing/prototyping/etc.

Repeats

Project management best practices: Working with clients in person

When working on a bigger project, the easiest way to improve you work relation with a client or an external product manager, is to make sure you see them in person once a while.

It makes sense to meet each other when you start working together to establish a relationship and find out what makes them tick.

If you need to discuss a larger package of work, use the opportunity and meet up and discuss it in person.

When you have to discuss something in your daily work, prefer talking to writing, and consider using a webcam.

Element is not clickable with chromedriver

Using chromedriver can sometimes lead to an Element is not clickable at point (...) error, when trying to click on an element.

This error occurs because chrome driver always tries to clicks the middle of the element after first identifying it's location.

So if you are trying to click on an element, the chrome driver tries to click at the position where it first finds that element. If the element is not at the same position where chrome driver has located it, the error "Element is not clickable at this position" is thrown.

A step which f…

Repeats

Escape a string for transportation in a URL

To safely transport an arbitrary string within a URL, you need to percent-encode characters that have a particular meaning in URLs, like & or =.

If you are using Rails URL helpers like movies_path(:query => ARBITRARY_STRING_HERE), Rails will take care of the encoding for you. If you are building URLs manually, you need to follow this guide.

Ruby

In Ruby, use CGI.escape:

CGI.escape('foo=foo&bar=bar')
=> "foo%3Dfoo%26bar%3Dbar"

Do not ever use URI.encode or …

Capistrano 2: How to deploy a single server

When you have a multi-server setup, you'll be adding a new server from time to time. Before doing a full deploy, you might want to test that server in an isolated deploy. There is a single way to do this: the HOSTFILTER env variable.

Commenting out "server" lines in the Capistrano deploy config will raise a Capistrano::NoMatchingServersError with <task> is only run for servers matching {:roles=> <role>}, but no servers matched. Instead, specify the server-under-test like this:

```
HOSTFILTER=separate-sidekiq.makandra.de cap productio…

Speed up better_errors

If you use the Better Errors gem, you will sometimes notice that it can be very slow. This is because it sometimes renders a huge amount of data that will actually be hard to render for your browser.

You can significantly improve performance by adding this to config/initializers/better_errors:

```
if defined?(BetterErrors) && Rails.env.development?
module BetterErrorsHugeInspectWarning
def inspect_value(obj)
inspected = obj.inspect
if inspected.size > 20_000
inspec…

MySQL 5.7.5 enables `ONLY_FULL_GROUP_BY` mode per default

When using GROUP BY, MySQL now complains if the SELECT includes columns which are not part of the GROUP BY.

Reason:

There could be multiple values for those columns per group but only one value can be picked for the results.

The default behaviour of MySQL prior to version 5.7 will not complain and arbitrarily choose a value. But this leads to non-deterministic results. So MySQL now has enabled the only_full_group_by setting by default to prevent this.

In Rails this could lead to some trouble, because scopes do not have sp…

Repeats

PSA: "index: true" in Rails migrations does not work as you'd expect

Several Rails migration methods accept index: true as an option to create an index. In some cases (like #add_column), this option is silently discarded. Know what you are doing, or use #add_index instead.

Example

Consider the following migration.

class CreateExamples < ActiveRecord::Migration
  def change
    create_table :examples do |t|
      t.references :category, index: true
      t.boolean :positive, index: true
      t.integer :number_of_participants, index: true
    end

    add_referen...

Rails 5's ApplicationRecord is the place to put generic model logic

Since Rails 5, domain models inherit from ApplicationRecord by default.

This is the place to put code that should be available in all your application's models.
There is no reason to monkey-patch ActiveRecord::Base when following that practice.

Repeats

How to split up a git commit

Quick steps

  1. git rebase -i -> mark your commit with edit
  2. git reset HEAD~ (remove the marked commit, but keep its changes)
  3. Make several commits
  4. git rebase --continue

Detailed instructions

Basically, you will review the last n commits and stop at the splittable commit. Then you'll undo that commit and put its changes into new commits at your liking.

  1. Review commits (rebase)

    git rebase -i HEAD~3
    # or
    git rebase -i origin/master
    

    Git will give you a list of commits, younge…

Repeats

Working with or without time zones in Rails applications

Rails supports time zones, but there are several pitfalls. Most importantly because Time.now and Time.current are completely different things and code from gems might use one or the other.

Especially configuring an application that cares only about one time zone is a bit tricky.

The following was tested on Rails 5.1 but should apply to Rails 4.2 as well.

Using only local time

Your life will be easier if your application does not need to support time zones. Disable them like this:

```
config.time_zone = 'Berlin' # Your local time…

View
3342 cards