views:

192

answers:

1

This is happening in an after_save method in one of my models, PlayerAction. I didn't change any code during the upgrade (famous last words). It appears to be happening on the following line:

if self.action_type.id == 1

The PlayerAction model has a

belongs_to :action_type

Changing action_type.id to action_type_id fixed that problem, but the same problem is happening in another place, in this line

player_action.action_type.desc

Here is the full stack trace, where the problem is occurring in that line

C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/belongs_to_association.rb:49:in `find'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/belongs_to_association.rb:49:in `send'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/belongs_to_association.rb:49:in `find_target'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/association_proxy.rb:240:in `load_target'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/association_proxy.rb:112:in `reload'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations.rb:1219:in `action_type'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:164:in `full_xml'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:160:in `each'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:160:in `full_xml'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:156:in `full_xml'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:136:in `full_xml'
C:/InstantRails2-0/rails_apps/rftg/app/models/game.rb:86:in `full_xml'
C:/InstantRails2-0/rails_apps/rftg/app/controllers/games_controller.rb:33:in `show'
C:/InstantRails2-0/rails_apps/rftg/app/controllers/games_controller.rb:30:in `show'

ActionType is another model of mine, and is a pretty generic name, as pointed out in another answer. Could that be the source of the problem? I looked in the main rails framework docs and didn't see a class or method named ActionType or action_type.

Turns out I did just add a custom find method for ActionType:

def self.find(id)
  Rails.cache.fetch(cache_key) { ActionType.find(id) }
end

ActionType is basically static data and I'm trying to cache it. There are about 10 rows for ActionType, and I have several other models that have similar static data. That's the whole reason I started the process to upgrade rails, to get that caching functionality. I've been trying to find an example of how to do this correctly. Clearly the above code isn't correct. I found another question here about the best-practice way to handle static data in a model, but it didn't quite help.

+2  A: 

try it with

if self.action_type_id == 1

At least you'll know if that's the problem.

Okay, seeing that that is a problem, per comments, the line in Rails it's dying on is in here:

def find_target
      find_method = if @reflection.options[:primary_key]
                      "find_by_#{@reflection.options[:primary_key]}"
                    else
                      "find"
                    end
      @reflection.klass.send(find_method,
        @owner[@reflection.primary_key_name],
        :select => @reflection.options[:select],
        :conditions => conditions,
        :include => @reflection.options[:include],
        :readonly => @reflection.options[:readonly]
      ) if @owner[@reflection.primary_key_name]
    end

I am assuming you are using "id" for the primary key, because it is dying in the find method which is reflectively invoked. Of course, that method takes (*args), so shouldn't be dying on the 2 for 1 problem...

So, a) have you defined some custom finder for this class (finder_sql?)

b) what is the full_xml method that this is in? Is that just the part where you call

 player_action.action_type.desc

?

MattMcKnight
That fixed it! Thanks! But can you tell me why?
I think I'd have to see the stack trace to hazard a guess.
MattMcKnight
I added the stack trace as well as another place where the same error is happening
Yes, full_xml is the method where the player_action.action_type.desc line is. I do not have a custom find method for this class. However, I am doing a PlayerAction.find() where I have includes and conditions arguments, and I just realized that ActionType is not in the include list.
It should be in there to prevent running the query too many times, but that shouldn't be causing the error.
MattMcKnight
Strike my last comment, I completely forgot that I did just add a custom find method for ActionType. See the details in the answer.