Skip to content

#devise_for should handle NoDatabaseError gracefully #5786

@cryptogopher

Description

@cryptogopher

Once Devise routes are configured using #devise_for, they are created always when application starts. #devise_for causes associated model to be loaded. If - for some reason - the model needs access to database on load, #devise_for causes unhandled exception if database does not exist. That effectively makes impossible to create non-existing database once #devise_for is added to routes.

Example:

routes.rb:

...
devise_for :users
...

app/models/user.rb:

...
validates :email, presence: true, uniqueness: true, length: {maximum: type_for_attribute(:email).limit}
...

Now, when trying to execute below command, unhandled exception happens:

rails db:create
bin/rails aborted!
ActiveRecord::NoDatabaseError: We could not find your database: database_name. Available database configurations can be found in config/database.yml. (ActiveRecord::NoDatabaseError)

To resolve this error:

- Did you not create the database, or did you delete it? To create the database, run:

    bin/rails db:create

- Has the database name changed? Verify that config/database.yml contains the correct database name.

Database can only be created if #devise_for is temporarily removed from routes.

Fragment of backtrace between #devise_for call and model loading:

...
/var/www/app/models/user.rb:1:in `<top (required)>'
/var/www/.gem/ruby/3.3.0/gems/zeitwerk-2.7.2/lib/zeitwerk/core_ext/kernel.rb:26:in `require'
/var/www/.gem/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/inflector/methods.rb:290:in `const_get'
/var/www/.gem/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/inflector/methods.rb:290:in `constantize'
/var/www/.gem/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/core_ext/string/inflections.rb:74:in `constantize'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise.rb:327:in `get'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/mapping.rb:83:in `to'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/mapping.rb:78:in `modules'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/mapping.rb:95:in `routes'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/mapping.rb:162:in `default_used_route'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/mapping.rb:72:in `initialize'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise.rb:361:in `new'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise.rb:361:in `add_mapping'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/rails/routes.rb:243:in `block in devise_for'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/rails/routes.rb:242:in `each'
/var/www/.gem/ruby/3.3.0/gems/devise-4.9.4/lib/devise/rails/routes.rb:242:in `devise_for'
/var/www/config/routes.rb:23:in `block in <top (required)>'
...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions