Posted about 2 years 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:

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.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Arne Hartherz
Last edit:
almost 2 years 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 short-lived cookies to improve usability.
Accept or learn more