1

Topic: ActiveRecord is getting confused between my Comment class and REXML's

I've noticed a few instances in my logs of errors when using ActiveRecord. I have a model named Comment. One of the errors happens when I do Comment.find. Another happens when I run find on a related model, and it reports the error as happening deep within ActiveRecord (trying to read table_name of the class). It's all intermittent. But both errors say that a method wasn't found on REXML::Comment. Is it confusing my Comment with REXML::Comment? Is there something I can do about this?

Re: ActiveRecord is getting confused between my Comment class and REXML's

Sounds like there is a conflict there, yes. Do you have any classes in the REXML scope that might be calling Comment? Or perhaps the REXML module is being included directly into one of your classes? It might be happening indirectly through something else.

Can you duplicate the error? If so, post the code which is apparently being called when the error happens. The stack trace will help too.

It is possible to make sure you are referencing the comment model and not REXML::Comment by doing this:

::Comment.find(:all)

The :: at the beginning will force it to look for a Comment class which isn't in a module. I don't really consider this as a solution since it isn't something you want to do everywhere.

Railscasts - Free Ruby on Rails Screencasts

3

Re: ActiveRecord is getting confused between my Comment class and REXML's

I have one class that imports REXML, but it's not one that's getting the errors. I can't reproduce it, it's just something I see in the logs. I also just noticed now that the errors happened together - the logs are over the course of an afternoon and there's one instance of 2 errors happening within a second of each other, and another instance of 4 errors happening together.

Stack 1:

NoMethodError (undefined method `find' for REXML::Comment:Class):
    /app/controllers/user_controller.rb:41:in `comments_on'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `send'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `send'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:150:in `process_request'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:54:in `process!'
    /usr/lib/ruby/1.8/fcgi.rb:600:in `each_cgi'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each_cgi'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:53:in `process!'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:23:in `process!'
    dispatch.fcgi:34

Code 1:

    def comments_on
        @user_displayed = User.find(@params["id"])
        if @user_displayed == nil
            return
        end
        @page_title = "Comments on styles by #{@user_displayed.name}"
        @comments = Comment.find(:all, :conditions => "styles.user_id = #{@params['id']}", :include => [:style, :user], :order => "comments.updated DESC")
        @type = "on"
        if params["mode"] == "atom" or params["mode"] == "rss"
            render(:action => "comment_feed", :layout => false)
        else
            @header_include = "<link rel=\"alternate\" title=\"Comments on styles by this user\" href=\"/user/comments_on/#{@user_displayed.id}/rss\" type=\"application/rss+xml\" />\n<link rel=\"alternate\" title=\"Comments on styles by this user\" href=\"/user/comments_on/#{@user_displayed.id}/atom\" type=\"application/atom+xml\" />"
            render(:action => "comment_list")
        end
    end

Stack 2:

NoMethodError (undefined method `table_name' for REXML::Comment:Class):
    (__DELEGATION__):2:in `__send__'
    (__DELEGATION__):2:in `table_name'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1410:in `initialize'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1296:in `new'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1296:in `build'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1303:in `build'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1302:in `each'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1302:in `build'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1299:in `build'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1298:in `each'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1298:in `build'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:1262:in `initialize'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:974:in `new'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:974:in `find_with_associations'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:973:in `catch'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/associations.rb:973:in `find_with_associations'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:923:in `find_every'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:918:in `find_initial'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:952:in `find_one'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:941:in `find_from_ids'
    /usr/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/base.rb:382:in `find'
    /app/controllers/style_controller.rb:61:in `show'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `send'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `send'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support'
    /usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:150:in `process_request'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:54:in `process!'
    /usr/lib/ruby/1.8/fcgi.rb:600:in `each_cgi'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each'
    /usr/lib/ruby/1.8/fcgi.rb:597:in `each_cgi'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:53:in `process!'
    /usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:23:in `process!'
    dispatch.fcgi:34

Code 2:
    def show
        #$ips << request.env["REMOTE_HOST"]
        if params.has_key?("raw")
            send_data StyleCode.find_by_style_id(params["id"]).code, :type => "text/css", :disposition => "inline"
            return
        end
        if params.has_key?("install")
            @style = Style.find(params["id"])
            #don't count installs by the author
            if session[:user] == nil or @style.user_id != @session[:user].id
                @style.increment_installs
            end
            send_data("OK", :type => "text/plain", :disposition => "inline")
            return
        end
        @style = Style.find(params["id"], :include => [{:comments => :user}, :user, :style_code], :order => "comments.updated DESC")
        @page_title = @style.short_description
        @header_include = "<link rel=\"stylish-code\" href=\"#stylish-code\"/>\n<link rel=\"stylish-description\" href=\"#stylish-description\"/>\n<link rel=\"stylish-update-url\" href=\"" + params["id"] + "?raw\"/>\n<link rel=\"stylish-install-ping-url\" href=\"" + params["id"] + "?install\"/>"
    end

Your suggestion may help for the first case, but the second case the Comment class isn't even referenced other than through the association.

Last edited by np (2007-01-18 20:54:38)

Re: ActiveRecord is getting confused between my Comment class and REXML's

That's strange you cannot duplicate the error, that makes it hard to troubleshoot. The parameters which were submitted with the request that caused the error should be in the log file. Did you try making the same request with the exact same parameters to see if it comes up again?

It may have something to do with the order that the classes are loaded in Ruby. If the REXML::Comment is loaded after the model it might take precedence.

I can't really think of a solution besides renaming the class. I'm sure there's an alternative, but I can't tell without testing.

Railscasts - Free Ruby on Rails Screencasts

5

Re: ActiveRecord is getting confused between my Comment class and REXML's

I don't think the parameters make a difference; I see other requests with the same parameters succeeded.

I'm leery to rename the class because I fear I'll just get a different kind of error and will have done the work for nothing. For now, I'll try to change the one case that actually references the class to ::Comment and see if stops that instance from happening.

6

Re: ActiveRecord is getting confused between my Comment class and REXML's

Even with ::Comments.find I got the error again. This time, I got a ton of errors. A page would work and then not work on refresh. It stopped when I touched dispatch.fcgi - maybe it's just a case of a process "going nuts".

Last edited by np (2007-02-01 01:36:49)

Re: ActiveRecord is getting confused between my Comment class and REXML's

I know Rails 1.2 handles loading of files slightly differently, perhaps upgrading will fix the problem? Other than that I'm not sure what to tell you. sad

Railscasts - Free Ruby on Rails Screencasts