views:

264

answers:

2

I have a legacy rails (version 1.2.3) app which runs without issue on a number of servers (not to mention my local environment). Deployed to its newest server, though, and I now get ActiveRecord::StatementInvalid: Mysql::Error: #23000Column 'video_id' cannot be null errors.

Below are the models/relationships, simplified:

class Video < ActiveRecord::Base
    has_one(:user, :dependent => :destroy)
end

class User < ActiveRecord::Base
    belongs_to(:video)
end

And below is a rails console transcript of the relationships failing:

>> video = Video.create(:title => 'New Video')
=> #<Video:0xb6d5e31c>...
>> video.id
=> 5
>> video.user = User.create(:name => 'Tester')
ActiveRecord::StatementInvalid: Mysql::Error: #23000Column 'video_id' cannot be null: INSERT INTO users (`name`, `video_id`) VALUES('Tester', NULL)
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract_adapter.rb:128:in `log'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:243:in `execute'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/mysql_adapter.rb:253:in `insert'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1811:in `create_without_callbacks'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:254:in `create_without_timestamps'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/timestamp.rb:39:in `create'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1789:in `create_or_update_without_callbacks'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:242:in `create_or_update'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1545:in `save_without_validation'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/validations.rb:752:in `save_without_transactions'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:129:in `save'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in `transaction'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:95:in `transaction'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:121:in `transaction'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:129:in `save'
    from /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:451:in `create'
    from (irb):3
    from :0

Has anyone else come across ActiveRecord not sending an ID when it clearly knows it?

+2  A: 

The correct syntax is

video.user.create(:name => 'Tester')

as you have it, it is trying to create the User before assigning it to video.user, per ruby order of evaluation.

mckeed
Or... `video.user = User.create(:name => 'Tester', :video_id => video.id)`. The reason is that you are creating the User model outside of the video and explicitly setting it. In this case, Rails will not jump in and do magic because you are doing things on your own. To avoid this use the above.
Tony Fontenot
This is an old app, though, and my syntax is in use in a number of locations without complaints. Giving the new syntax a go yields: NoMethodError: You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.create from (irb):3 from :0
Metric Scantlings
Sorry, you're right. I forgot that User.create will return the record if it can't save it.
mckeed
A: 

Well, I've migrated this particular portion of this well-aged app to rails 2.3.5 and the following now does the trick:

video.create_user(:name => 'Tester')

Thanks for the input so far, but if anyone has any idea why the 1.2.3 version of the code works on every server it has met until today (older ActiveRecord disagreeing with a certain version MySQL in some obscure way, maybe?) I'd love to hear it.

Metric Scantlings