I changed my mind about this since I sent my last response:

I think doing anything outside of modifying the database (*seeding is
pushing it, but I think in some cases it is acceptable*) is definitely a
hack.


Reflecting on the history of Rails, particularly what led to the addition
of seed.rb and the rake db:seed - I realized even seeding the database in
migrations is a bad idea in all cases - unless the migrations DSL provides
a way to do that and have that reflected in schema.rb/sql, which I don't
believe is possible.

I think, the rule of thumb is that if you are doing anything in your
migrations that would case your schema.rb/sql + seed.rb to be out of sync
with your actual database state (i.e. running db:schema:load and db:seed is
not sufficient to boot a fresh instance of your app), then you are doing it
wrong.

The best way to do seeding is to make sure your seed.rb is "one-way
idempotent" (as in - running db:seed multiple times on incremental
rollbacks would not create duplicate data, etc. Use find_or_create_by and
friends to help) and run that after every deploy together with db:migrate.
Of course, when it comes to rolling back a deploy, you'd still have to
figure out what to do with those data on a case-by-case basis, but that's
expected for any non-idempotent actions you perform on deploy.
Alternatively, if you engineered a custom framework/workflow for these
after deploy actions (deploy-specific cap scripts and whatnot), then you
could do the seeding there, but you'd still want to keep your seed.rb up to
date.


On Mon, Feb 18, 2013 at 4:27 AM, Godfrey Chan <[email protected]> wrote:

> @mrloz
>
> I think doing anything outside of modifying the database (seeding is
> pushing it, but I think in some cases it is acceptable) is definitely a
> hack. The immediately obvious problem with that solution is that some of
> the tasks you described is not idempotent, such as sending emails. This
> might case problem if you experienced problems with your new deploy and had
> to roll back the changes temporarily and revert the rollback at a later
> time. You can raise an exception on rollback, but since you'll have to
> determine how to manually recover from the broken state (and how to restore
> it later), I don't quite see what you are gaining here.
>
> Deployment is one of the few things that Rails doesn't manage for you
> since it is difficult to come up with a general framework that is a good
> enough starting point for most people. Migrations is designed specifically
> to manage changes to your database schema, and is not technically tied your
> deployment flow (while you might just automatically run db:migrate on every
> deploy, it is not exactly straight forward to keep your schema in sync with
> your code on rollback).
>
> So, because Rails doesn't dictate how you manage your deployment workflow,
> you'd just have to engineer your own solution that works for your
> particular deployment flow.
>
> @rodrigo
>
> Even if you just modify schemas, the only reliable way I know of
> recreating your db is to run all migrations.
>
> ...
>
> This doesn't work for many cases if your schema format is :ruby (the
> default).
>
> ...
>
> Unless you use :sql for schema_format of course.
>
>
> I think you kind of had it backwards:
>
> 1. The purpose of schema.rb/sql is exactly what the guides described - to
> recreate the database schema on a new instance of the app without having to
> re-run all the migrations.
>
> 2. You are correct that schema_format = :ruby does not support
> vendor-specific features like HStores or other "advanced" SQL features like
> foreign key constraints.
>
> From 1 & 2, the obvious conclusion should be that "If you are using any
> vendor-specific or advanced SQL features, you should turn on schema_format
> = :sql" instead of "If you are using any vendor-specific or advanced SQL
> features, you should re-run all your migrations on a fresh deploy."
>
> As for the foreign-key constraints debate, IIRC it was quite controversial
> in the early days of Rails, but it's a largely settled debate. There are
> still different opinions on this of course, but at the end of the day Rails
> would have to pick a default convention, and "intelligence belongs in
> your models" have won. And hence schema_format = :ruby is the default.
> (With new AR features like hstore support on the horizon, that decision
> might worth a revisit, but that'd be a separate discussion.)
>
> You can still choose to use vendor-specific or advanced SQL features of
> course, hence the ability to toggle that setting to :sql.
>
> Godfrey
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to