Posted about 1 month ago. Visible to the public.

When reading model columns during class definition, you must handle a missing/empty database

When doing some meta-programming magic and you want to do something for all attributes of a class, you may need to access connection or some of its methods (e.g. columns) during class definition.

While everything will be fine while you are working on a project that is in active development, the application will fail to boot when the database is missing or has no tables. This means that Raketasks like db:create or db:migrate fail on a freshly cloned project.

The reason is your environment.rb which is loaded for Raketasks and calls Rails.application.initialize! which in turn may/will evaluate classes. If one of those classes is tries to access its database connection, you will encounter fun errors such as:

  • PG::ConnectionBad (for missing databases on PostgreSQL)
  • ActiveRecord::StatementInvalid: PG::UndefinedTable (when database exists, but has no tables)

Generally speaking, evaluating model columns during class definition is not a bad thing, but you need to make it work when the model has no database or database columns yet. Example:

Copy
class Post < ApplicationRecord begin # Magically auto-strips all string attributes columns.each do |column| next if [:string, :text].exclude?(column.type) attribute_name = column.name class_eval <<~RUBY, __FILE__, __LINE__ + 1 def #{attribute_name}=(value) super(value.to_s.strip.presence) end RUBY end rescue PG::ConnectionBad, ActiveRecord::StatementInvalid # When the database does not exist at all or is missing a model's table, # accessing "columns" raises an error and the application fails to boot. # # To allow calling "rake db:create" or "rake db:migrate" on an empty # database, we swallow such errors. end end

For MySQL, rescue Mysql2::Error, ActiveRecord::StatementInvalid might be fitting.

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for old versions of Ruby on Rails (3.2 and 2.3).

Owner of this card:

Avatar
Arne Hartherz
Last edit:
about 1 month ago
by Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more