Out with database.yml

Is there a real use case for the Ruby config? Anyone have a story of something they could do with the .rb and not do with the .yml?

::Jack Danger

To keep this discussion on track, forget I said that abou the db host and db name. :slight_smile: But there's no reason to keep the adaptor, encoding, or socket location secret.

(In theory, if your safe is secure, it doesn't matter if the thief knows where it is. It doesn't even matter if he knows how it's built. In practice, I agree that every little bit helps, even the most incidental bit of obscurity.)

    - Scott

To keep this discussion on track, forget I said that abou the db host and db name. :slight_smile: But there's no reason to keep the adaptor, encoding, or socket location secret.

I don't want you to know /anything/ about the databases I'm using. Including the adapter and socket location(s) (if I have them at all, which I won't tell you ;).

(In theory, if your safe is secure, it doesn't matter if the thief knows where it is. It doesn't even matter if he knows how it's built. In practice, I agree that every little bit helps, even the most incidental bit of obscurity.)    It does matter, because you can damage the safe without actually cracking the code making the safe inaccessible to the owner.

My point is that I don't want /any/ info wrt the production databases under source control. I don't see how moving stuff into ruby code adds any value. It's not like there's something dynamic going on for which you need the power of ruby.

Lawrence

Btw, what about email credentials? Currently the only way to define the smtp_settings for ActionMailer::Base is via ruby code. If we're sticking to database.yml, shouldn't we have an email.yml as well?

sure, I can do e.g.:

ActionMailer::Base.smtp_settings = YAML::load(ERB.new(IO.read(RAILS_ROOT + "/config/email.yml")).result)[env]

in my environment.rb, but then I can do that for database.yml as well if that was what's needed.

Lawrence

I concur with Ezra on this. It's very nice to have the database config in a single place that other applications in other languages can easily reference.

Sure you can.

It’ll just be a larger pain in the ass.

http://slantwisedesign.com/rdoc/yaml_mail_config/ puts email config in yaml, ferret and backgroundrb store their info in yml and on occasion I've stored environment-specific config code in yaml.

Is the ruby config released as a gem? If not, I suggest that you release it as a gem. Bonus points if it has a generator that creates the necessary files (newgem rocks for creating things like that).

I think will_paginate should be in core, but it's not, and I have to config.gem it to every app I have, but I don't mind since it's so hip. If people think ruby database configs are hip, they won't mind adding a line to each new app they have and running a generator.

Personally I don't see the need for it, and I probably wouldn't install the gem. Further, if rails shipped with it I'd probably opt to keep using yaml just because I've got several apps with capistrano recipes and backup scripts that I like to keep them up to date with the latest released version of rails.

If the behaviour you mean is simply to ensure that production credentials are loaded from an external file, there are surely simpler ways of doing this than building a Ruby DSL (loathe as I am to use that word, but you get what I mean).

My concern is that this is *too much solution*, even for the benefits that it claims, and keeping Rails lithe and slim should be a priority.

The problems with the current setup need to be much clearer - "database.yml is workable, but its a little weird at this point" isn't sufficient reason to change, IMHO. Weird how? I'm not suggesting that it isn't weird, but we should have some explicit reasons or examples.

Likewise, "there is no other instance of YAML configuration in one's app when it runs in production" is a bit misleading: the database is the *only common external dependency* in a Rails application. It is a description of something outside of the Ruby process (unlike any ruby libraries or frameworks you might be loading). If every Rails application had to also interface with, say, Solr, we'd probably have a config/solr.yml file too.

As Frederick Cheung points out, another solution to the "DRY" concern is using YAML in a smarter way. Rick suggested that "[it's] a lot harder to read and write, especially for newbies", but we could solve that by providing comments in the file to educate. Making the change to a ruby-based configuration will still confuse newbies, thanks to Google and all the tutorial pages that won't be updated.

In a nutshell, lets be sure that we're solving genuine problems and/or providing tangible benefits, before we make the framework that little bit more complicated.

I can see where you are coming from with this patch, but while we're at it wouldn't it be better to support the standard credential mechanisms for the database in question as well.

For example with mysql there is a file called ~/.my.cnf that can hold the credentials necessary for the 'mysql' tool to log onto the database. It is a simple ini file. Similarly with postgres there is the ~/.pgpass file

I would really like to see a three layer system here

- Use the database tool set credential storing mechanism if it has one. - Override with credential details from database.yml for backward compatibility. - Override with ruby config credential details from the environments, if specified.

That way you can keep your credentials out of Rails completely if you want *and* have it DRY with the toolset you are using.

Right so we're back to a single file containing the database logon details, only this time we've scattered some of the config in four other files as well rather than keeping it all nicely together.

Struggling to see how that helps anybody.

Your change moves the database details from one file for all environments to separate specifications in the environment files as well as changing the format. So there are two separate debates here.

- moving away from the yml format. We could simply go for 'database.rb' containing a details hash per environment. Essentially replicating the existing structure in Ruby format. - moving away from the single file to the multiple environment file approach. But then you want to put an exception in forcing people to source credentials from some other file. I don't see the benefit in that. Just do it in one place.

I can see the advantage of getting rid of YML for the database connection specification, but I think your "don't version control the credentials" opinionation sort of torpedoes the 'put the database details directly in the environment files' idea.

To go the whole hog surely we need a 'development_database.rb', 'test_database.rb' and 'production_database.rb' set of files in config/ environments where the differences between the environments can be expressed *and* excluded from version control. This way you still get the advantage of factoring the common stuff into the main 'environment.rb' file - something that is less than can be done in YAML but only if you know the incantation.

Rails will than look for a <environment>.rb and <environment>_database.rb file when it loads the environment.

I definitely agree with Matt's sentiments. You can count me in for a -1. Good effort though.

James