Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 6.0.0.beta1 can not load database configuration when the URL (or database) is nil #35091

Closed
msdundar opened this issue Jan 29, 2019 · 8 comments · Fixed by #35102
Closed

Comments

@msdundar
Copy link

msdundar commented Jan 29, 2019

Steps to reproduce

Here is a part of the database configuration we use:

<% name = 'my_fancy_app'
   url = "postgresql://#{name}:#{name}@localhost/#{name}_%{environment}" %>

default: &default
  adapter: postgresql
  pool: 5
  timeout: 5000
  encoding: unicode

development:
  <<: *default
  url: <%= format url, environment: 'development' %>

test:
  <<: *default
  url: <%= format url, environment: 'test' %>

production: &production
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
  pool: <%= ENV.fetch('RAILS_MAX_THREADS', 40) %>

beta:
  <<: *production

In Rails 5.2.2 when I call ActiveRecord::Base.configurations['production'] it returns:

{"adapter"=>"postgresql", "pool"=>40, "timeout"=>5000, "encoding"=>"unicode", "url"=>nil}

However, in Rails 6.0.0.beta1 ActiveRecord::Base.configurations['production'] it returns:

nil

Expected behavior

ActiveRecord::Base.configurations should return the existing database variables as it was in Rails 5.2.2.

Actual behavior

Rails 6.0.0.beta1 returns nil when the url (or database) is nil somehow.

System configuration

Rails version:

  • Rails 6.0.0.beta1

Ruby version:

Tested with both:

  • ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
  • ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
@msdundar msdundar changed the title Rails 6.0.0.beta1 can not load database configuration when the URL is nil Rails 6.0.0.beta1 can not load database configuration when the URL (or database) is nil Jan 29, 2019
@gmcgibbon
Copy link
Member

Seems to happen when ENV['DATABASE_URL'] is nil on this line. I'll try to fix it.

@msdundar
Copy link
Author

Somehow this caused a test suite fail in CircleCI. The logs were stating a fail to read database configuration for beta and production environments, even I can verify ENV['DATABASE_URL'] is defined and accessable. As a workaround I added database: foo_bar line to the configuration and it worked well.

@gmcgibbon
Copy link
Member

Given that URL configurations do this, I think this use-case is no longer supported. There's special code for ENV["DATABASE_URL"] that transforms the current environment's config to a URL config, so if you remove the url: setting in production and add database: "", that should work, but that seems like a hack.

cc @eileencodes

@eileencodes
Copy link
Member

eileencodes commented Jan 30, 2019

What does ActiveRecord::Base.configurations return? In Rails 6 configurations aren't a hash, they're an object so ActiveRecord::Base.configurations['production'] won't work anymore. It was an unfortunate change we had to make to improve the overall problem.

You can instead use ActiveRecord::Base.configurations.configs_for(env_name: "production") to get production configurations back.

Eh that wasn't true, I forgot I implemented the ability to use [] with the objects.

@msdundar
Copy link
Author

msdundar commented Jan 30, 2019

ActiveRecord::Base.configurations.configs_for(env_name: "production") returns nil when the url is nil. However there are other parameters available for the production configuration, and it totally omits them.

  • database.yml: As on the issue body.
ActiveRecord::Base.configurations.configs_for(env_name: "development")

=>

[#<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00005568d23caee8
  @config=
   {"adapter"=>"postgresql",
    "pool"=>5,
    "timeout"=>5000,
    "encoding"=>"unicode",
    "username"=>"my_fancy_app",
    "password"=>"my_fancy_app",
    "database"=>"my_fancy_app_development",
    "host"=>"localhost"},
  @env_name="development",
  @spec_name="primary",
  @url="postgresql://nokul:nokul@localhost/nokul_development">]
ActiveRecord::Base.configurations.configs_for(env_name: "production")

=>

nil

I would expect something like this instead of nil when ENV['DATABASE_URL'] is nil:

[#<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00005568d23caee8
  @config=
   {"adapter"=>"postgresql",
    "pool"=>5,
    "timeout"=>5000,
    "encoding"=>"unicode",
    "username"=>"my_fancy_app",
    "password"=>"my_fancy_app",
    "database"=>nil,
    "host"=>nil},
  @env_name="production",
  @spec_name="primary",
  @url=nil>]

@eileencodes
Copy link
Member

I'm confused, why are you using the production configuration if the database url isn't set?

@msdundar
Copy link
Author

Actually I noticed the changing behavior when I'm trying to make a deploy to Dokku. After the Rails 6.0.0.beta1 upgrade, during the bundle exec rake assets:precompile stage, the container started to complain as follows:

ActiveRecord::AdapterNotSpecified: The `beta` database is not configured for the `beta` environment.

Available databases configurations are:

development
test

We have never changed the database.yml, it is working without any problems when the app in Rails 5.2.2. We only upgraded to Rails 6.0.0 and it started to fail. So I believe that this is something related with the modified behaviour?

@eileencodes
Copy link
Member

eileencodes commented Jan 30, 2019

Ok I was able to reproduce this and am working on a fix. One thing I'd like clarification on is I'm guessing the beta in 5.2 doesn't blow up but doesn't work either because without the database url it would not be able to connect right? Can you tell me what happens with the beta connection in 5.2.2? Thanks!

eileencodes added a commit to eileencodes/rails that referenced this issue Jan 30, 2019
Previously if the `url` key in a config hash was nil we'd ignore the
configuration as invalid. This can happen when you're relying on a
`DATABASE_URL` in the env and that is not set in the environment.

```
production:
  <<: *default
  url: ENV['DATABASE_URL']
```

This PR fixes that case by checking if there is a `url` key in the
config instead of checking if the `url` is not nil in the config.

In addition to changing the conditional we then need to build a url hash
to merge with the original hash in the `UrlConfig` object.

Fixes rails#35091
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants