Nil error on ActiveRecord::save!

How is the current object (self) associated with the user object? The
references to AssociationProxy in the stacktrace may be pointing in
that direction (malformed has_many/habtm/etc).

AndyV

I think you are right - this seems to me to be the only explanation for
this cryptic error about which I cannot see any more details. Thanks a
lot for suggesting it. I have a very simple polymorphic association set
up

activity.rb
belongs_to :transactionable, :polymorphic=>:true
belongs_to :user

user.rb
has_many :activities

and finally

transfer.rb
has_one :activity, :through=>:transactionable

So there is no fancy association between user and activity, just
belongs_to/has_many.
I am simply trying to get to the user from the activity with
activity.user.save! The polymorphic association is not even involved
here.

I know see one of the major drawbacks of Ruby as a language: very poor
error messages.

Thanks,
V

AndyV wrote:

Sure, here is the full error:

NoMethodError in ActivitiesController#new

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+

RAILS_ROOT: script/../config/..
Application Trace | Framework Trace | Full Trace

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/locking/optimistic.rb:64:in
`update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:267:in
`update_without_timestamps'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/timestamp.rb:39:in
`update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1792:in
`create_or_update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:242:in
`create_or_update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1554:in
`save_without_validation!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/validations.rb:762:in
`save_without_transactions!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:95:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:121:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`method_missing'
/home/victor/workspaces/grow/app/controllers/activities_controller.rb:76:in
`update_user_balance'
/home/victor/workspaces/grow/app/controllers/activities_controller.rb:33:in
`new'

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/locking/optimistic.rb:64:in
`update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:267:in
`update_without_timestamps'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/timestamp.rb:39:in
`update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1792:in
`create_or_update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:242:in
`create_or_update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1554:in
`save_without_validation!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/validations.rb:762:in
`save_without_transactions!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:95:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:121:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`method_missing'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:1101:in
`send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:1101:in
`perform_action_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:696:in
`call_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:688:in
`perform_action_without_benchmark'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/rescue.rb:83:in
`perform_action'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in
`send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in
`process_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:684:in
`process_without_session_management_support'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/session_management.rb:114:in
`process'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:334:in
`process'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/dispatcher.rb:41:in
`dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:113:in
`handle_dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:79:in
`service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:63:in
`dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/servers/webrick.rb:59
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in
`require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in
`new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in
`require'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/server.rb:39
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/locking/optimistic.rb:64:in
`update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:267:in
`update_without_timestamps'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/timestamp.rb:39:in
`update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1792:in
`create_or_update_without_callbacks'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/callbacks.rb:242:in
`create_or_update'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/base.rb:1554:in
`save_without_validation!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/validations.rb:762:in
`save_without_transactions!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:95:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:121:in
`transaction'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/transactions.rb:133:in
`save!'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`send'
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/associations/association_proxy.rb:123:in
`method_missing'
/home/victor/workspaces/grow/app/controllers/activities_controller.rb:76:in
`update_user_balance'
/home/victor/workspaces/grow/app/controllers/activities_controller.rb:33:in
`new'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:1101:in
`send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:1101:in
`perform_action_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:696:in
`call_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:688:in
`perform_action_without_benchmark'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/rescue.rb:83:in
`perform_action'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in
`send'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:435:in
`process_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/filters.rb:684:in
`process_without_session_management_support'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/session_management.rb:114:in
`process'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/base.rb:334:in
`process'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/dispatcher.rb:41:in
`dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:113:in
`handle_dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:79:in
`service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/webrick_server.rb:63:in
`dispatch'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/servers/webrick.rb:59
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in
`require'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in
`new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in
`require'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.5/lib/commands/server.rb:39
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
script/server:3

Request

Parameters: {"commit"=>"Save changes", "transfer"=>{"approval"=>"true"},
"activity"=>{"size"=>"1", "transactionable_type"=>"Transfer",
"description"=>"a", "user_id"=>"3"}}

Show session dump

And what is in this file?

/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/locking/optimistic.rb:64:in

I'd bet it has something to do with lock_version being nil.

There should be a much bigger backtrace than just that. Show us all of it please.

What exactly would that mean and how would I fix it?
If you want to see a larger stacktrace how would I get that?

Thanks.

Rick Olson wrote:

Victor,

First off, you really should learn not to top-post, adding your
comments to the end rather than the beginning of messages (after
appropriately trimming what's being quoted, makes it much easier to
follow the thread.

That said, let me expand on Rick's sage nudge on what to look for.

Here are three lines from
/usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/locking/optimistic.rb
starting with line 62, as the name of the file implies this has to do
with ActiveRecord's optimistic locking feature.

        lock_col = self.class.locking_column
        previous_value = send(lock_col)
        send(lock_col + '=', previous_value + 1)

Now what's blowing up is that previous_value + 1, and previous_value
is obviously nil from the error message.

Where did previous value come from? Well it came from an attribute in
the AR object whose name came from the class method locking_column,
which unless you've overridden it, will return the name of the
standard attribute name which AR uses for the lock field which is
lock_version.

Note that you posted this:

#<User:0xb70ea1e8 @attributes={"salt"=>"L8Qymoyol2O7rA==",
"updated_at"=>"2007-12-30 09:58:06", "details"=>"Valentin Chilaru, New
York NY", "lock_version"=>nil,
...

Showing that lock_version is indeed nil.

Okay, now that we know that, we need to look at how AR expects you to
set up lock_version. By convention it should be an integer field with
a default value of 0, and this should be defined in a migration.

class FixLockVersionInUser < ActiveRecord::Migration
    def self.up
         execute "UPDATE users SET lock_version = 0 WHERE lock_version IS NULL"
         change_column :users, :lock_version, :integer, :default => 0
    end

    def self.down
        # You can probably just leave this out but to be pro-forma we
put things back the way they were on a down.
        change_column :users, :lock_version, :integer
    end
end

That said, let me expand on Rick's sage nudge on what to look for.

Thanks for expanding that, Rick :slight_smile:

FWIW, Rails 2.0.x should fix this by calling #to_i on the nil value
first. I can't remember exactly when the fix was applied, so it might
be in the next release of rails. It's definitely in edge.

Hey, we Ricks need to hang together! <G>

Rick Denatale wrote: