View
Repeats

How to use Rails URL helpers in any Ruby class

In Rails 3+, you can use:

class Project
  delegate :url_helpers, to: 'Rails.application.routes'

  def project_path
    url_helpers.project_path(self)
  end
end

For Rails 2, use the attached Modularity trait. It will give any Ruby class a method #url_writer, on which you can call URL helpers:

class Foo
  does 'write_urls'
  def self.class_method
    url_writer.session_path
  end
  def instance_method
    url_writer.project_path(5)
  end
end
Repeats

Ruby: Natural sort strings with Umlauts and other funny characters

Why string sorting sucks in vanilla Ruby

Ruby's sort method doesn't work as expected with German umlauts:

["Schwertner", "Schöler"].sort
=> ["Schwertner", "Schöler"] # you probably expected ["Schöler", "Schwertner"]

Also numbers in strings will be sorted character by character which you probably don't want:

["1", "2", "11"].sort
# => ["1", "11", "2"] # you probably expected ["1", "2", "11"]

Also the sorting is case sensitive:

["a", "B"].sort
# => ["B", "a"] # yo...
Linked contentAuto-destruct in 50 days

Updated: Install RubyMine under Ubuntu

RubyMine gibt es jetzt als Snap, eine neuere Art, Pakete zu installieren. Vorteil ist, dass man einem channel (wie stable, 2017.3/stable) folgt und automatisch die aktuellste Version des Channels installiert wird.

Repeats

Merge two arbitrary ActiveRecord scopes

Rails 3+ allows you to join two scopes from arbitrary sources by calling the merge method:

scope1 = User.where(:email => 'foo@bar.com')
scope2 = User.where(:first_name => 'hans')
merged_scope = scope1.merge(scope2)

merged_scope.all will now trigger a query for the combined scope chain:

SELECT `users`.* FROM `users` WHERE `users`.`email` = 'foo@bar.com' AND `users`.`first_name` = 'hans'

If you are joining two models, you can also [merge scopes for different models](http://blog.thefrontiergroup.com.au/2011/03/composing-…

Repeats

ActiveRecord scopes must be loaded before using RSpec's "=~" matcher

To test whether two arrays have the same elements regardless of order, RSpec gives you the =~ matcher:

actual_array.should =~ expected_array

If either side is an ActiveRecord scope rather than an array, you should call to_a on it first, since =~ does not play nice with scopes:

actual_scope.to_a.should =~ expected_scope.to_a

Using ES6 without a transpiler

If your app does not need to support IE11, you can use most ES6 features without a build step. Just deliver your plain JavaScript without transpilation through Babel or TypeScript, and modern browsers will run them natively.

Features supported by all modern browsers include:

  • fat arrow functions (() => { expr })
  • let / const
  • class
  • async / await
  • Promises
  • Generators
  • Symbols
  • Rest arguments (...args)
  • Destructuring

You won't be able to use import and export, or use npm modules.

See this [ES6 compatibility mat…

Linked contentRepeats

Custom error messages in RSpec or Cucumber steps

Sometimes you have a test expectation but actually want a better error message in case of a failure. Here is how to do that.

Background

Consider this test:

User.last.should be_present

In case of an error, it will fail with a not-so-helpful error message:

expected present? to return true, got false (Spec::Expectations::ExpectationNotMetError)

Solution

That can be fixed easily. RSpec expectations allow you to pass an error message like this:

User.last.should be_present, 'Could not find a user!'

Now your test will…

Repeats

How to emulate simple classes with plain JavaScript

If you want a class-like construct in JavaScript, you can use the module pattern below. The module pattern gives you basic class concepts like a constructor, private state, public methods.

Since the module pattern only uses basic JavaScript, your code will run in any browser. You don't need CoffeeScript or an ES6 transpiler like Babel.

A cosmetic benefit is that the module pattern works without the use of this or prototypes.

Example

Here is an example for a Ruby class that we want to translate into Javascript using the module patter…

Repeats

Summarizing heredoc in ruby and rails

This card tries to summarize by example the different uses of heredoc.

  • In Ruby << vs. <<- vs. <<~
  • In Rails strip_heredoc vs. squish

strip_heredoc should be used for a text, where you want to preserve newlines. (multi-line -> multi-line)

squish should be used for a text, where you want to squish newlines. (multi-line -> one-line)

Ruby

def foo
  bar = <<TEXT
line1
line2
line3
TEXT
  puts bar.inspect
end
foo => "line1\nline2\nline3\n"

```
def foo
bar = «TEXT
line1
line2
line3
TEXT
puts bar.in…

Repeats

How to overwrite and reset constants within Cucumber features

Note: Prefer to not configure your app using global constants. Prefer to set keys in Rails.configuration instead (in application.rb).


In order to save the original value of a constant, set the new value and restore the old value after a scenario was completed, you can use the following helper. It takes care of saving the old constant value, setting the new one without throwing warnings and resets the value with an After hook.

This module also enables you to introduce new global constants.
Since thes…

Upgrading Ruby from 1.8.7 to 2.3.5

Suggested Workflow

Set the ruby version in .ruby-version to 2.3.5, then perform these steps one by one, fixing errors as they occur:

1) Update gems as listed below, and bundle
2) Boot a Rails console
3) Run Specs with --backtrace option
4) Run Cucumber features (with Geordi's --debug option)
5) When all tests are green, look through your Gemfile and remove as many version constraints as possible

Gem updates

  • Replace ruby-debug with byebug or pry
  • Replace mysql with mysql2, '< 0.3'
  • Remove oniguruma
  • Remove…

How to create a Basic Auth header value

When doing Basic Authentication, your browser will send an "Authorization" header. Its value is simply a Base64-encoded representation of "username:password" (like when you place credentials in the URL directly). Example for "user@example.com" with password "secret":

Authorization: Basic dXNlckBleGFtcGxlLmNvbTpzZWNyZXQ=

So, in Ruby, you can create such headers like so:

Base64.strict_encode64("#{username}:#{password}")

Note that when speaking to a REST API, you should be using libraries like RestClient or HTTParty which will wrap …

Repeats

Copying validation errors from one attribute to another

When using virtual attributes, the attached trait can be useful to automatically copy errors from one attribute to another.

Here is a typical use case where Paperclip creates a virtual attribute :attachment, but there are validations on both :attachment and :attachment_file_name. If the form has a file picker on :attachment, you would like to highlight it with errors from any attribute:

class Note < ActiveRecord::Base
  has_attached_file :attachment
  validates_attachment_presenc...

Ruby: Reading and writing CSVs

In ruby you can easily read and write CSVs with the standard CSV library class.

On top of this, you can use the gem smarter_csv for reading (not writing) CSVs in a more comfortable way:

  • Keep in mind, that the development of this gem is in an unknown state and the 2.0 release seems to happen never
  • The API will change completely for 2.0, so you might find a bunch of unrelated documentation for 1.2

Here is an example…

Make ActionMailer use the current request host and protocol for URL generation

When you generate a URL in a mailer view, ActionMailer will raise an error unless you previously configured it which hostname to use. Configuring the correct hostname is quite annoying when you have multiple deployment targets with different hostnames, e.g. a staging server and a production server.

Using the hack below you don't need to configure a default hostname for your mailers. They will always use the hostname for the current request:

class ApplicationController < ActionController::Base

  before_filter :make_action_maile...
Deprecated

Live CSS / view reloading

Next time you have to do more than trivial CSS changes on a project, you probably want to have live CSS reloading, so every time you safe your css, the browser updates automatically. It's pretty easy to set up and will safe you a lot of time in the long run. It will also instantly reload changes to your html views.

Simply follow the instructions below, taken from blog.55minutes.com.

Install CSS live reload (only once per project)

  1. Add th…
Repeats

Cucumber Factory: How to assign polymorphic associations

Cucumber factory supports polymorphic associations out of the box. Just keep in mind that you need to use named associations for this purpose.

class Person < ApplicationModel
  has_many :buildings, inverse_of: :owner
end

class Company < ApplicationModel
  has_many :buildings, inverse_of: :owner
end

class Building < ApplicationModel
  belongs_to :owner, optional: true, polymorphic: true
end

Works

```
Given there is a person with the name "Nice person"
And there is a buildin…

Linked contentRepeats

The Easiest Way to Parse URLs with JavaScript

A very clever hack to parse a structured URL object is to create a <a> element and set its href to the URL you want to parse.

You can then query the <a> element for its components like schema, hostname, port, pathname, query, hash:

var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'

if (pathname[0] != '/')
  pathname = '/' + pathname // Fix IE11

One advantag…

This website uses cookies to improve usability and analyze traffic.
Accept or learn more