rake db:create error:"Unknown database"

If my code tries to access the database at "compile time", e.g.
defining methods based on values in a table, the rake db:create task
fails:

  rake aborted!
  #42000Unknown database 'xxx_development'

Why does the db:create task need to load the entire application in
order to create the database, instead of just reading database.yml?

I'm not the first to see this, e.g.
http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/6c7b2901a6bc6cde/06e149bd53c650d8

and http://www.ruby-forum.com/topic/154561

Cheers
Dave

I'm just curious why you find it to be a problem that it loads the
environment?

Well, I agree that that's kind of silly. When you have a very large app,
it can take quite a bit of time to load the environment... And, when
we're talking about just creating a db, I don't see why we need the
environment. Then again, I never use db:create... I just use mysqladmin.

b

Andrew Bloom wrote:

I think loading the environment with db:create and db:drop is
unnecessary. I've run into scenarios where a plugin does some
initialization based on the database and raises exceptions if there is
no database (ultrasphinx and acts_as_ferret are two that come to
mind).

Whenever I set up an app on a new machine, and I have a plugin that
expects a database installed, I have to script/dbconsole to create the
database. It's not world-ending, but it is annoying.

I always run into this with the betternestedset plugin. I have to edit the model before I can recreate the database.

As you said, nothing terrible, but why load the whole environment if all you need is some stuff in a config file?

Matt Darby**, M.S.**

Rails | PHP | Linux | MySQL | IT

Email: matt@matt-darby.com

Skype: matt-darby

Web: http://blog.matt-darby.com

Also, it seems, based on the 2 threads I linked in the original post,
that this behaviour was introduced in rails 2.1 -- but I haven't
confirmed that myself.

In my case (replying to Andrew Bloom's question), I was automatically
defining helper methods like "admin?", "student?", etc, based on data
in the roles table, to save typing "current_user.has_role?(:admin)"
etc... my code was smart enough to not fail if the roles table was
missing (so that at least the migrations creating the roles table
wouldn't fail), but I wasn't checking for the presence of the entire
database. rake db:create fails before creating the database, because
it loads my application, which expects a database!

I agree that it's not a huge issue, but you know, I think rails could
do with some tidying up before the next million new features are
added. :slight_smile: For someone relatively new to rails like myself, all these
small issues add up and bite one or two days out of every week of
work. I don't mean to criticise anyone that works on rails, your work
is hugely appreciated, and I realise I should be submitting patches
myself if I want things to improve (once I get my head around the
rails code). But I feel like I have been battling against the
framework far more than necessary. Hopefully rails has reached a high
enough level of maturity, feature-wise, that bug-fixes will be given
priority over new features.

Dave.

To add to the bikeshet color palette ...

rails code). But I feel like I have been battling against the
framework far more than necessary.

As I see it it's an education problem - at least for the examples mentioned.

Plugins like better_nested_set are clearly framework level plugins (extending ActiveRecord features). As such they should not make any assumptions about a database being present and it should be possible to implement it like that I guess. *)

Also, plugin models that act_as_nested_set cause this problem only if they are loaded during plugin loading time. Avoid that the model is loaded when the plugin's init.rb is loaded and the problem will go away. Again, to me this seems, even if obscure and hard to teach, rather like an education problem (because the plugin has been designed the wrong way) than a problem with rake tasks requiring the environment (which generally makes sense).

*) (There are application level plugins out there for which it *might* make sense to make assumptions about the database but they also can't because Rails still has no concept of application level plugins ... but that's a different story :wink:

+1 on this comment, and I don't think this should be considered a
plugin design flaw.

This thread is like deja vu of the database.yml vs. environment config thread.

I still believe that any *external* dependencies or resources
(databases, gems) should get special treatment. In other words, if
there is a dependency which is external to the app, any rails
provisions for managing it should not be dependent on the app
initializing first. Otherwise, it's a chicken and egg problem.
That's why db:create should not depend on the app initializing, and
also (shameless plug) why I'd prefer the GemInstaller (which has
standalone as well as integrated invocation options) over config.gems
for managing gems, including the Rails gem(s) itself :slight_smile:

-- Chad