Problem running back-to-back migrations


#1

Hi All,

I running Ruby/Rails versions:
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
Rails 2.0.2

I ran:
ruby script/generate scaffold Payroll string:Client_Code
and got 001_create_payrolls.rb:
class CreatePayrolls < ActiveRecord::Migration
def self.up
create_table :payrolls do |t|
t.Client_Code :string

  t.timestamps
end

end

def self.down
drop_table :payrolls
end
end

I didn’t want to add all the variables I wanted to the scaffold
invocation. So I created a second migration 002_create_payrolls.rb:
class CreatePayrolls < ActiveRecord::Migration
def self.up
create_table :payrolls do |t|
t.Client_Code :string
t.Date :date
[snip]
t.EE_Num :integer

  t.timestamps
end

end

def self.down
drop_table :payrolls
end
end

Here’s the problem. I ran:
rake db:migrate
and got:
– create_table(:payrolls)
rake aborted!
undefined method `Client_Code’ for
#ActiveRecord::ConnectionAdapters::TableDefinition:0x3154278

I thought the problem might be that 001 created the payrolls database,
and 002 did the same thing … an obvious conflict. So I modified 002
to precede the create_table statement with:
drop_table(:payrolls)
That gave me:
== 2 CreatePayrolls: migrating =======================================
– drop_table(:payrolls)
rake aborted!
SQLite3::SQLException: no such table: payrolls: DROP TABLE payrolls

I tried running with the –trace option but it failed immediately the
same way.

I realize I could just replace 001’s content with 002’s and discarding
002. Or I could switch 002 to add_column statements. But I’d like
to learn how these multiple migrations work.

Any observations would be most appreciated.

TIA,
Richard


#2

Hi Richard
What I have found when working with a sequence of migrations is that you
don’t really know the state of your database when something bombs. I
suggest that when you come up with a different set of code for your
migrations, you manually place the database in a known initial state
(maybe rake db:migrate VERSION=0) and then try to run you migrations
from that spot. Otherwise I have ended up with tables being created
when I thought they had not or not being created when I had thought they
had been.

The migrations are great when you get them figured out but if you are
cramming data in as you do migrations it can get interesting.

Good luck
Norm


#3

On Oct 23, 3:02 pm, RichardOnRails
removed_email_address@domain.invalid wrote:

def self.up
end

rake db:migrate
That gave me:
to learn how these multiple migrations work.

Any observations would be most appreciated.

You can’t create a table twice (well, there might be a
create_or_replace sql type thing going on, but putting that
aside…). Your second migration needs to be altered to add the
columns in, instead. ‘self.down’ will then need to remove them.
Use ‘add_column’ and ‘remove_column’ methods.
Check your docs or see
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001161
Your 1st migration is doing a ‘CREATE TABLE’ sql; whereas your 2nd is
doing an ‘ALTER TABLE’ sql.

Then reset all the damage above with:
rake db:migrate VERSION=0
(If that fails, recreate the (development) database - the rake command
escapes me; easy to just delete it if it’s sqlite3. Make sure you
have no valuable data in there)
then run
rake db:migrate


Daniel B.


#4

RichardOnRails wrote:

  t.Client_Code :string

The rails convension is is to make the column names lower case. So
this should be:
t.client_code :string

I think (but I haven’t checked) that you actually need to write this
as:
t.string :client_code

I don’t think there is a fancy method_missing implementation that
creates columns names based on method calls. (I could be wrong here.)

See this for more info:
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#M001231


#5

Hi y’all,

I’ve got just one final problem: my CRUD offers functionality only for
the field I listed in my scaffolding. Despite the fact that I created
and successfully executed an addition fixture, none of those fields is
included in the CRUD.

The only way I can think of to generate CRUD for all my fields is to
redo my scaffolding with all the fields listed in that command.
That’ll generate the fixture equivalent to my second fixture, for
which I’ll have no immediate need.

IMHO, listing all those fields on a scaffold command is an ugly
approach, when compared to the second fixture that listed all the
fields. Is there an easier way?

Thanks in advance,
Richard

On Oct 23, 7:58 am, RichardOnRails


#6

RichardOnRails wrote:

IMHO, listing all those fields on a scaffold command is an ugly
approach, when compared to the second fixture that listed all the
fields. Is there an easier way?

Scaffolding is really only a learning tool or a way to jump start
development. It gets you going quickly with some decent patterns, but
you expected to customize them heavily. That is why the new fields
don’t get added automatically.

But you might be interested in checking out: http://activescaffold.com/


#7

Scaffolding is really only a learning tool or a way to jump start …
Understood. Still, in development mode, it would be nice to have the
Rails 1.x functionality still working. But I’ll grudgingly accept the
judgment of the Rails Masters :slight_smile:

http://activescaffold.com/
That’s very helpful Because it looks like a good basis for writing a
Ruby DB-updating app to complement the Rails app.

I’m also looking into “ActiveRecord with ar-extensions” (http://
www.igvita.com/2007/07/11/efficient-updates-data-import-in-rails/)

But all this is grist for a new thread some other day.

Best wishes,
Richard


#8

Hi All,

Sorry. Mea culpa. Another stupid error: I had the “name:type” syntax
backwards. After I straightened that out everywhere, I:

  1. ran the first migration alone – ran OK
  2. created the second migration
  3. ran the second migration – ran OK

BTW, I added “, :force => true” in the second migration because I
thought it necessary since I was replacing the first table definition
with an expanded definition. Was that really necessary?

I haven’t confirmed the database is constructed correctly (using SQL),
but I’ll get to that now.

I hope none of you labored over my long script.

Best wishes,
Richard

On Oct 23, 12:02 am, RichardOnRails


#9

Hi Roy,

http://helloimbloggingatyounow.blogspot.com/2008/03/i-am-leet-rails-h

Nice work. I haven’t tried it out because I already re-did my
scaffolding supplying all the column-names I needed. But I’'ve stored
your blog’s URL to consider trying your tool for my next Rails
application.

Best wishes,
Richard


#10

Agree that scaffolding in 2.x is unnecessarily hobbled. FWIW–here’s
what I wound up doing:

http://helloimbloggingatyounow.blogspot.com/2008/03/i-am-leet-rails-haxor.html

or if that breaks:

http://is.gd/4IRI

It’s worked reasonably well for me.