Posted 9 months ago. Visible to the public. Repeats.

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:

class Post < ApplicationRecord begin # Magically auto-strips all string attributes columns.each do |column| next if [:string, :text].exclude?(column.type) attribute_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.

By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.

Owner of this card:

Arne Hartherz
Last edit:
6 months 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