Looking at the log, you see things such as:
So...where does referring_friend get introduced?
NoMethodError: undefined method `referring_friend' for #<user:0x2aaab3936628>
251_add_promo_to_user.rb
class AddPromoToUser < ActiveRecord::Migration
def self.up
if User.table_exists? && !User.column_names.include?('referring_friend')
add_column :users, :referring_friend, :string
end
end
def self.down
if User.table_exists? && User.column_names.include?('referring_friend')
remove_column :users, :referring_friend
end
end
end
OK, clearly this works and we have some additional checks in place. Specifically, don't add the column if it already exists and don't drop it if it's not there. Doing either of these could cause some database errors.
Nice, but we still don't know why it's failing. Let's have a look at what cruise does
custom_cc.rake
See the problem yet?
...
task :cruise do
['test_env_init', 'db:rollback', 'db:migrate','test', 'spec:cruise:rcov'].each do |task|
...
Let's see what's happening in that cruise task.
- test_env_init - pretty simple, just sets the RAILS_ENV to test
- db:rollback - runs the down for the latest migration. So in this case we
remove_column :users, :referring_friend
- db:migrate - runs the latest migrations. So in this case we
However...we only drop the column if it exists and we only add it if it's not already there
add_column :users, :referring_friend, :string
OK, so let's try this in our good friend, script/console:
$ script/console
Loading test environment (Rails 2.0.2)
>> puts User.column_names.include?('referring_friend')
true
=> nil
>> exit
$ rake db:rollback
(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)
== 251 AddPromoToUser: reverting ==============================================
-- remove_column(:users, :referring_friend)
-> 0.1270s
== 251 AddPromoToUser: reverted (0.3239s) =====================================
$ script/console
Loading test environment (Rails 2.0.2)
>> puts User.column_names.include?('referring_friend')
false
=> nil
>> exit
$ rake db:migrate
(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)
== 251 AddPromoToUser: migrating ==============================================
-- add_column(:users, :referring_friend, :string)
-> 0.0739s
== 251 AddPromoToUser: migrated (0.2668s) =====================================
$ script/console
Loading test environment (Rails 2.0.2)
>> puts User.column_names.include?('referring_friend')
true
=> nil
>>
Hmm...that all looks correct. But that wasn't actually a good test of what's happening because we're "Loading test environment" every time we run script/console.
Let's try that again using 2 different sell sessions.
Session 1
$ script/console
>> puts User.column_names.include?('referring_friend')
true
Session 2
$ rake db:rollback
(in /usr/local/cruise/cruisecontrolrb-1.2.1/projects/release_1_7/work)
== 251 AddPromoToUser: reverting ==============================================
-- remove_column(:users, :referring_friend)
-> 0.1799s
== 251 AddPromoToUser: reverted (0.3748s) =====================================
Session 1
>> puts User.column_names.include?('referring_friend')
true
Session 2
$ psql -U cruise_test -d cruise_test_1_7
$ \d users;
*As we expected, there's no referring_friend column on the Uses table
Session 1
>> User.reset_column_information
=> nil
>> puts User.column_names.include?('referring_friend')
false
Ah ha!!
So, if we update our User model after each change, the build should Colt 45 (it works every time)
updated 251_add_promo_to_user.rb
class AddPromoToUser < ActiveRecord::Migration
def self.up
if User.table_exists? && !User.column_names.include?('referring_friend')
add_column :users, :referring_friend, :string
User.reset_column_information
end
end
def self.down
if User.table_exists? && User.column_names.include?('referring_friend')
remove_column :users, :referring_friend
User.reset_column_information
end
end
end
No comments:
Post a Comment