postgresql create extension without giving the application superuser rights

If you need a postgresql extension for your database it isn't a good idea to give your applications database user superuser rights (like many people on stackoverflow think)

Just login to the database with a superuser account (e.g. postgres) and create the extension with it.

Example:

# with the default configuration of postgresql you normally can login as `postgres` user
# without a password if you use the systems `postgres` user
$ sudo su -l postgres
$ pgsql
postgres=# \c your_database;
psql (9.3.9, server 9.3.5)
You are now connected...

ActiveRecord: scoped `validates_uniqueness_of` allows one null value per scope

As you most likely know validates_uniqness_of :foreign_id does not allow nil values by default.

To allow nil one has to set the :allow_nil => true option.

Very unexpected scoping this validation will not raise an error if foreign_id set to nil for the first created record of this kind.

validates_uniqueness_of :foreign_id, :scope => :another_column # allows foreign_id to be nil

Without a validation for presence of foreign_id now unusual records could be created.

How to deal with 'parent id missing' error in nested forms

tl;dr

  • Use form models to handle this problem
  • Or soften the validation to validates_presence_of :parent

Usually you would validate presence of parent object id, like in this example:

class Parent < ActiveRecord::Base
  has_many :nested, :inverse_of => :parent
  accepts_nested_attributes_for :nested
end

class Nested < ActiveRecord::Base
  belongs_to :parent
  validates_presence_of :parent_id # <- 
end

With the parent already persisted creating nesteds still works fine.

But one will encounter a *'parent id missing' er...

How to enable SSL in development with Passenger standalone

Here is how to start your Rails application to accept both HTTP and HTTPS in development.

  1. gem install passenger

  2. Create a self-signed SSL certificate. Store the generated files in config/passenger-standalone-ssl.

  3. Create a Passengerfile.json at the project root with this content (or save the attached file):

    {
      "ssl": true,
      "ssl_port": 3001,
      "ssl_certificate": "config/passenger-standalone-ssl/server.crt",
    

    ...

Getting Sidekiq error "delay is defined by Active Record"

Reason: You very likely have a model that has a delay attribute.

You can configure Sidekiq to remove its delay method by adding this to your Sidekiq initializer:

Sidekiq.remove_delay!

If you need to keep Sidekiqs delay features, add Sidekiq.hook_rails! before the option above. The sidekiq methods will be prefixed with sidekiq_ then.

PostgreSQL: Be careful when creating records with specific ids

In tests, it is sometimes useful to create records with specific ids. On PostgreSQL this can cause problems:

Usually, PostgreSQL uses an "autoincrement" sequences to provide sequential ids for new database rows. However, these sequences will not increment if you insert a record "by hand". This will cause an error:

record = Record.create!
record.id                             # => 100, next automatic id will be 101
Record.create!(id: record.id + 1)     # okay, but next automatic id will still be 101
Record.create!                       ...

Mocking time in Jasmine specs

The easiest way to freeze or travel through time in a Jasmine spec is to use the built-in jasmine.clock().

  • After jasmine.clock().install() you can use it to control setTimeout and setInterval.
  • Using jasmine.clock().mockDate() you can mock new Date() (which returns the current time in Javascript)

While you can use SinonJS Fake timers, using the built-in Jasmine clock will save you an extra dependency.

Detecting N+1 queries with Bullet

The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.

Rails 4.2 Foreign Key Support

The migration DSL now supports adding and removing foreign keys. They are dumped to schema.rb as well. At this time, only the mysql, mysql2 and postgresql adapters support foreign keys. @rubyonrails

Workings

add_foreign_key(:comments, :users)

adds a database constraint

ALTER TABLE "comments" ADD CONSTRAINT comments_user_id_fk FOREIGN KEY ("user_id") REFERENCES "user" ("id")

Disadvantage

Foreign key constraints double the validatio...

JavaScript events: target vs currentTarget

tl;dr: Use event.currentTarget unless you are absolutely certain that you need event.target.


Since it hasn't been written down in this deck before, here it goes:

When working with JavaScript Event objects, the DOM element that triggered the event is attached to them. [1]
However, there are 2 "opinions" on which element that would be:

  • The element that the user interacted with (event.target),
  • or the element that the event listener is bound to (event.currentTarget).

Note that both can be, but not...

How to capture changes in after_commit

Your after_commit callbacks will not know about changes, as Rails discards them when committing.

The linked article shows a clever trick to work around that: It uses an after_save method that looks at changes and writes its decision to an instance variable. That instance variable can then be used in the after_commit method.

Note that while callbacks like after_save are not affected, there are valid reasons for using only after_commit, and not after_save. Enqueueing a Sidekiq job is just one of them.

Rails 5+

You can use ...

24 little known CSS facts

This blew my mind today:

Please make sure to check browser support for CSS features on Can I Use and the Mozilla Development Network before using.

Favorites

  • outline-offset: specify how far away from the element an outline is rendered
  • ::first-letter: matches the first letter insid...

emcien/iso_latte

Sometimes you need to run background jobs that you can't make important guarantees about - they may run out of memory and get killed, or produce segmentation faults, or exit! directly - and you need to be able to clean up after such problems.

IsoLatte is a gem that allows a block of code to be executed in a subprocess. Exceptions get passed back to the parent process through a pipe, and various exit conditions are handled via configurable callbacks.

Protip: Clone large projects multiple times

Large projects usually have large test suites that can run for a long time.
This can be annoying as running tests blocks you from picking up the next story -- but it doesn't have to be that way!

Simply clone your project's repo twice (or even more often).

When your work on a feature branch is done, simply push that branch and check it out on your 2nd copy to run tests there.
You can pick up a new story and work on that on your "main" project directory.

If you do it right, you will even be able to run tests in both your 2nd copy and your m...

FactoryGirl: How to easily create users with first and last name

In most of our applications, users have their first and last name stored in separate columns. However, specifying them separately quickly gets annoying, especially when proxying them from cucumber_factory:

Given there is a user with the first name "Dominik" and the last name "Schöler"

Wouldn't it be nice if you could just say:

Given there is a user with the name "Dominik Schöler"

and have FactoryGirl assign first and last name automatically? The code below achieves that!

##...

How to disable auto-complete on login forms

Disabling auto-complete in login forms is probably a bad idea, since it encourages weak passwords.

If you are still forced to implement this (maybe due to legal or policy requirements), this is how:

Prevent browsers from saving the password in the first place. Disabling autocomplete does not improve security.

How to prevent password saving:

To prevent the browser from saving passwords (and usernames), you need to:

  • copy username and password to hidden form fields before submitting the login form
  • c...

Faster debugging with RubyMine macros

In my RubyMine I have recorded two macros for debugging and linked them to some keyboard shortcuts. Since I believe everyone could benefit from having those I wanted to share this.

The first one simply inserts

binding.pry

and the second one

.tap { |object| binding.pry }

for when you do not have a reference to the object you want to inspect.

In order to record a macro you simply follow the path Edit > Macros > Start Macro Recording.

Then you simply type binding.pry or whatever you want to record and stop recor...

Casting ActiveRecord scopes or instances to ActiveType extended model classes

When working with ActiveType you will often find it useful to cast an ActiveRecord instance to its extended ActiveType::Record variant.

Starting with active_type 0.4.0 you can use ActiveType.cast for this:

class User < ActiveRecord::Base
  ...
end

class SignUp < ActiveType::Record[User]
  ...
end

user = User.find(1)
sign_up = ActiveType.cast(user, SignUp)
sign_up.is_a?(SignUp) # => true

This is basically like [ActiveRecord#becomes](http://apidock.com/rails/v4.2.1/ActiveRecord/...

Rails 3 ActiveRecord::Persistence#becomes does not copy changed attributes

Note: ActiveRecord::Base#becomes has a lot of quirks and inconsistent behavior. You probably want to use ActiveType.cast instead.


This issue will be encountered when relying on attribute_was methods of ActiveModel::Dirty after casting a model which has defaults to a form model, for example.

In my case a record with an assignable_values legacy value beca...

Databases don't order rows unless you tell them so

There is no such thing as a "default order" of rows in database tables.

For instance, when you paginate a result set: When using LIMIT, it is important to use an ORDER BY clause that constrains the result rows into a unique order. Otherwise you will get an unpredictable subset of the query's rows. You might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering? The ordering is unknown, unless you specified ORDER BY.

In Rails, if you use Record.first or Record.last, it will default to orderin...

High Performance Browser Networking: HTTP/2

HTTP/2 will make our applications faster, simpler, and more robust—a rare combination—by allowing us to undo many of the HTTP/1.1 workarounds previously done within our applications and address these concerns within the transport layer itself. Even better, it also opens up a number of entirely new opportunities to optimize our applications and improve performance!

Querying model errors in Rails 4

ActiveModel supplies an errors object that behaves similar to a Hash. It can be used to add errors to a record, as well as to query the record for registered errors. This object is returned when calling <object>.errors:

errors = @user.errors # => #<ActiveModel::Errors ...>

Here are some helpful messages of its API:


[<attribute name>]

Returns an array of error messages on that attribute. Example: errors[:name] => ['is missing']


add_on_blank(<attribute list>) (similarly add_on_empty)

Registers an error ...

sessionStorage: Per-window browser storage

All major browsers (IE8+, FF3.5+, Safari 4+, any Chrome) support sessionStorage, a JavaScript storage object that

  • survives page reloads and browser restores,
  • but is different per new tab/window (in contrast to localStorage which is shared across all tabs).

MDN says:

The sessionStorage object is most useful for hanging on to temporary data that should be saved and restored if the browser is accidentally refreshed

Demo

Example usage:

Show details of TLS/SSL connections of remote hosts

sslscan is a nice tool to show details about TLS/SSL connections:

~> sslscan some-host-at.makandra.de

Testing SSL server some-host-at.makandra.de on port 443

  Supported Server Cipher(s):
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-SHA384
    Rejected  SSLv3  256 bits  ECDHE-RSA-AES256-SHA
...

  Prefered Server Cipher(s):
    TLSv1  128 bits  ECDHE-RSA-A...