View
Auto-destruct in 60 days

assignable_values now supports Array attributes

Assignable values can now also be used for array values. This works when you use Rails 5+ and PostgreSQL with an array column, or on older Rails versions and other databases using ActiveRecord's serialize.

To validate array values, pass multiple: true:

class Song < ActiveRecord::Base
  serialize :genres   # skip this when you use PostgreSQL and an array type column

  assignable_values_for :genres, multiple: true do
    ['pop', 'rock', 'electronic']
  end
end

In this case, every subset of the given values is valid, for examp…

How to let passenger restart after deployment with capistrano

Phusion Passenger changed the way how it gets restarted several times. Through the project's history, these all were valid:

  • touch tmp/restart.txt
  • sudo passenger-config restart-app /path/to/app
  • passenger-config restart-app /path/to/app

You should not need to know which one to use. Instead, the capistrano-passenger gem will choose the appropriate restart mechanism automatically based on your installed the passenger version.

Installation

  1. Add to your Gemfile:

    gem 'capistr...
    
External contentRepeats

Rspec: Scope your custom matchers to example groups

When you find yourself in the situation that you would like to define a custom matcher in your specs, but you do not want to define a global matcher since you need it only for your specific test, then you can simply put it in a module and include it only where you need it.

Since each describe block generates an anonymous class internally, this will include the matcher for this example group only.

```
require 'rspec/expectations'

module MyHelpers
extend RSpec::Matchers::DSL

matcher :be_just_like do expected  
match { actual a…
Repeats

Rails: When to use :inverse_of in has_many, has_one or belongs_to associations

When you have two models in a has_many, has_one or belongs_to association, the :inverse_of option in Rails tells ActiveRecord that they're two sides of the same association.

Example with a has_many / belongs_to association:

class Forum < ActiveRecord::Base
  has_many :posts, :inverse_of => :forum
end

class Post < ActiveRecord::Base
  belongs_to :forum, :inverse_of => :posts
end

Knowing the other side of the same association Rails can optimize object loading so forum and forum.posts[0].forum will reference the same…

External content

The Definitive Guide to Cookie Domains

Restricting access to cookies is essential for security in many web apps. For example, the session ID, the secret token used to identify a particular session, is typically stored in a cookie. Cookies have several important settings. Previously, I discussed the secure flag. This time, let’s dive into the cookie domain.

The cookie domain is an important security feature, probably even more important than the secure flag. It tells the browser that this cookie must only be sent to matching domains. Matching however, can happen in several w…

Repeats

Test if two date ranges overlap in Ruby or Rails

A check if two date or time ranges A and B overlap needs to cover a lot of cases:

1. A partially overlaps B

2. A surrounds B

3. B surrounds A

4. A occurs entirely after B

5. B occurs entirely after A

This means you actually have to check that:

  • neither does A occur entirely after B (meaning A.start > B.end)
  • nor does B occur entirely after A (meaning B.start > A.end)

Flipping this, A and B overlap iff A.start <= B.end && B.start <= A.end

The code below shows how to implement this in Ruby on Rails. The example is a clas…

An incomplete guide to migrate a Rails application from paperclip to carrierwave

In this example we assume that not only the storage gem changes but also the file structure on disc.

A general approach

Part A: Create a commit which includes a script that allows you to copy the existing file to the new file structure.

Part B: Create a commit which removes all paperclip logic and replace it with the same code you used in the first commit

Part A

Here are some implementation details you might want to reuse:

  • Use the existing models to read the files from
  • Use your own carrierwave models to write t…

Colcade is a lightweight Masonry alternative

Masonry is a famous library to dynamically arrange a grid of items that have different aspect ratio, like horizontal and vertical images. Colcade is an alternative masonry-layouting library, developed by the same developer, but with a more modern approach.

It is said to have better performance while being smaller and having no dependencies. It automagically detects jQuery and defines a jQuery initializer, if present.
However, it offers [a few less features](https:…

Repeats

Always, always declare your associations with symbols

Never ever declare your associations with a string, especially when doing metaprogramming. A common mistake is something like

# WRONG
class Page < ActiveRecord::Base
  %w[main sub].each do |type|
    belongs_to "#{type}_title"
  end
end

   
# RIGHT
class Page < ActiveRecord::Base
  %w[main sub].each do |type|
    belongs_to "#{type}_title".to_sym
  end
end

Always append a to_sym, otherwise you'll have [all](/makandra/4177-bugfix-rails-does-not-find-an-association-when-it-is-nam…

Rails: How to check if a certain validation failed

If validations failed for a record, and you want to find out if a specific one failed, you can do this via Rails.
You should rarely need this, as your error messages are usually good enough to display all necessary information to users.

As an example, consider the following model which uses two validations on the email attribute.

class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true
end

And let's assume we have a blank user:

user = User.new
user.valid? # => false

The record's errors then…

Repeats

Collect all values for a given column in an ActiveRecord scope

The Edge Rider gem allows you to collect an array of values for one field of your ActiveRecord elements:

>> User.active.collect_column(:id)
=> [1, 5, 23, 42]

It also comes with a :distinct option in case you are only interested in unique values:

>> Article.collect_column(:state, distinct: true)
=> ['draft', 'published']

In modern Railses (since 3.2) you can also use ActiveRecord's pluck met…

Repeats

Your Rails sandbox console

Just found out about a great feature in Rails that seems to be around since Rails 2. Start a console with the --sandbox (or -s) parameter:

rails console --sandbox

All changes you make to the database will be rolled back on exit. Very safety, much great, so secure. Wow!

Repeats

Cancelling the ActiveRecord callback chain

What Rails version Within before_* Within after_*
Cancel later callbacks Rails 1-4 return false return false
Cancel later callbacks Rails 5 throw :abort throw :abort
Rollback the transaction Rails 1-4 return false raise ActiveRecord::Rollback
Rollback the transaction Rails 5 `throw…  
Repeats

Case sensitivity in PostgreSQL

PostgreSQL, unlike MySQL, treats strings as case sensitive in all circumstances.

This includes

  • comparison with = and LIKE
  • collision detection in unique indexes

Usually this is fine, but some strings (like emails and usernames) should typically be treated as case insensitive.

There are a few workarounds available:

  • use the citext extension
  • use ILIKE instead of LIKE
  • use Postgres' lower() function
  • add an index on lower(email)

Probably the best approach is…

Repeats

Rails < 5: How to get after_commit callbacks fired in tests

If you use transactional_fixtures or the database_cleaner gem with strategy :transaction, after_commit callbacks will not be fired in your tests.

Rails 5

Rails 5 has a fix for this issue and no further action is needed.

Rails 3+

Add the gem test_after_commit to your test group in the Gemfile and you are done. You don't need to change the database strategy to deletion (which might…

Repeats

Do not use "flex: 1" or "flex-basis: 0" inside "flex-direction: column" when you need to support IE11

Flexbox is awesome. Most of it even works in IE11, but flex: 1 won't work reliably in Internet Explorer.
This it because implicitly sets flex-basis: 0 which IE fails to support properly.

Example

Consider the following HTML and CSS.

<div class="container">
  <div class="child">
    foo
  </div>
  <div class="bar">
    bar
  </div>
</div>
.container {
  display: flex;
  flex-direction: column;
}

.child {
  flex: 1;
}

See it in action at Plunker.

Background

Repeats

Nested ActiveRecord transaction pitfalls

When working with custom transactions you may encounter unexpected behaviour if you try to roll back your changes.

tl;dr

Not all databases support nested transactions. Therefore, Rails will sometimes silently ignore a nested transaction and simply reuse the other transaction. However, a ActiveRecord::Rollback within the nested transaction will be caught by the block of the nested transaction, but will be ignored by the outer transaction, and not cause a roll back!
To avoid this unexpected behaviour, you have to explicitly tell rai…

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