Topic: ActiveRecord::ConfigurationError: Association [...] was not found

Disclaimer: Any of this might be in grossly bad form, I've *just* begun with rails AND ruby...

I'll attempt to lay out the problem with enough information for diagnosis, but not so much information that it's completely unusable.  I'll ask my question at the end (with the error message)


Types Model:

  class Type < ActiveRecord::Base
    [...]
    has_many :things
    [...]
  end

Types Database Table:
  mysql> describe types;
  +-------+--------------+------+-----+---------+----------------+
  | Field | Type         | Null | Key | Default | Extra          |
  +-------+--------------+------+-----+---------+----------------+
  | id    | int(11)      | NO   | PRI | NULL    | auto_increment |
  | name  | varchar(255) | YES  |     | NULL    |                |
  +-------+--------------+------+-----+---------+----------------+

Things Model:
  class Thing < ActiveRecord::Base
    [...]
    belongs_to :type
    [...]
  end

Things Controller:
  [...]
  def show
    @thing = Thing.find(params[:id], :include => [:type])
    [...]
  end
  [...]

Things Database Table
  mysql> describe things;
  +---------------+--------------+------+-----+---------+----------------+
  | Field         | Type         | Null | Key | Default | Extra          |
  +---------------+--------------+------+-----+---------+----------------+
  | id            | int(11)      | NO   | PRI | NULL    | auto_increment |
  | name          | varchar(255) | YES  | MUL | NULL    |                |
  | type_id       | int(11)      | YES  | MUL | NULL    |                |
  [...]
  +---------------+--------------+------+-----+---------+----------------+

Test Code:
  [...]
  fixtures :things, :types
  [...]
  def test_show
    get :show, :id => 1
  end
  [...]

Types fixtures:
  first:
    id: 1
    name: type_one
  another:
    id: 2
    name: type_two

Things fixtures:
    first:
    id: 1
    name: thing_one
    type_id: 1
  another:
    id: 2
    name: thing_two
    type_id: 2

  # rake test
    [...]
    ActiveRecord::ConfigurationError: Association named 'type' was not found; perhaps you misspelled it?
    [...]

So, now I have no idea why I'm getting this error message.  When viewed in the web page the type_id is appropriately translated via @thing.type.name to the proper name.  I have to admit right here that today is my first day attempting to use tests, so if the answer is devastatingly obvious I apologize in advance!

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Type is a reserved word, so I bet that's the problem. Try renaming it and see if it works.

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

OK, the names had all been changed to protect the guilty here, Type is actually Protocol

My apologies for using a reserved word as its replacement that was kind of thick skulled of me.  So as far as I've been able to tell nothing in the translated equation is a ruby or rails reserved word

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Try running this command to make sure the testing database has the proper schema:

rake db:test:clone

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Interesting there was a problem with the schema, a problem with adding a key on a text field.  The key wasnt immediately necessary (and completely unrelated to the relationship) so I removed it.  I can now do a rake db:test:clone with no problem, but I still get the error

.oO(apokalyptik@home ~/test) rake db:test:clone --trace
  (in /home/apokalyptik/test)
  ** Invoke db:test:clone (first_time)
  ** Invoke db:schema:dump (first_time)
  ** Invoke environment (first_time)
  ** Execute environment
  ** Execute db:schema:dump
  ** Execute db:test:clone
  ** Invoke db:schema:load (first_time)
  ** Invoke environment
  ** Execute db:schema:load
.oO(apokalyptik@home ~/test)

  [...]
  Started
  .......E...........................................
  Finished in 0.744694 seconds.
 
    1) Error
  test_show(ThingsControllerTest):
  ActiveRecord::ConfigurationError: Association named 'protocol' was not found; perhaps you misspelled it?
  [...]

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Weird, so everything is working fine in the browser, the error only comes up when testing? It also looks like you have a lot of tests and this is the only one that's failing. The only thing that seems uncommon to me is the use of :include inside a find(id) statement. This seems to be fully supported though.

What happens if you remove the :include portion of that find? Do you still get the error, only later on when protocol is referenced in the view?

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Exactly my thoughts! Wierd!  When I take out the :include from the controller, the error changes

  ActionView::TemplateError: undefined method `protocol' for #<Thing:0xb768e8d8>

which is attached to this line of code:

  <p><label>Protocol:</label> <%= if @Thing.protocol != nil then h @hotspot.protocol.name end %></p>

Re: ActiveRecord::ConfigurationError: Association [...] was not found

It sounds like the belongs_to association isn't getting called in the test case. Would you mind posting your Thing model? (Probably under a different name). You can exclude the methods if you want.

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

The really weird thing is that it works - in a browser - with and without the include (I assumed the include was necessary to follow the associations, seems I was wrong)

class Thing < ActiveRecord::Base
  require 'hpricot'
  require '../components/abbr.rb'
 
  belongs_to :protocol
  belongs_to :type
  belongs_to :network
  belongs_to :user
  has_many :comments
  validates_presence_of :name, :protocol_id, :type_id, :network_id, :address1, :city, :country
  validates_length_of :name, :within => 3..128
  validates_length_of :address1, :within => 6..128

  def validate_on_create
    errors.add_to_base 'Thing needs to be unique!' unless validates_thing_unique?
    errors.add_to_base '' unless validates_abbr?
  end
 
  def validate_on_update
    errors.add_to_base '' unless validates_abbr?
  end
 
  def validates_thing_unique?
    @fthing = Thing.find :all, :conditions => [' name = ? and address1 = ? and state = ? and country = ?', self.name, self.address1, self.state, self.country ]
    if @fthing.length > 0
      return false
    else
      return true
    end
  end
 
  # BEGIN -- Responsible for converting country and state
  #          nouns to abbreviations before saving them.
  #          in conjunction with a call in both validate_on_create
  #          and validate_on_update above. and the abbr.rb and
  #          abbr.xml file located in components
  def validates_abbr?
    self.country = find_country_abbr self.country
    self.state = find_state_abbr self.state, self.country
    return true
  end
  # END
 
  # BEGIN -- Responsible for translating country and state
  #          abbreviations to nouns before display in
  #          conjunction with the alias_method call *below*
  #          and the abbr.rb and abbr.xml file located in
  #          components
  def after_find_func
    self.state = find_state_name self.state, self.country
    self.country = find_country_name self.country
  end
  alias_method :after_find, :after_find_func
  ## END
 
end

Re: ActiveRecord::ConfigurationError: Association [...] was not found

AH HAH!!!! I GOT IT!

  require '../components/abbr.rb'

becomes

  require File.dirname(__FILE__) + '/../../components/abbr.rb'

The pathing worked in the web browser but not in the test who's base path must be set differently...  I'd run into similar things with the VIEWS while trying to figure out testing, but the error was very obvious... this was insidious!

but it works, all the tests pass now! WOO!

As a side note I had to come up with a home baked way of storing country and state names as abbreviations and displaying them as full names.  Is there a better way to do this? If not I'll be happy to post my abbr.xml and abbr.rb somewhere because it might be ugly and hacky but it works

Re: ActiveRecord::ConfigurationError: Association [...] was not found

not the views, the controllers, I'm sorry. Point remains... it works smile

Re: ActiveRecord::ConfigurationError: Association [...] was not found

Edit: Nevermind, looks like it works now. smile

Last edited by ryanb (2006-12-07 14:01:37)

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

apokalyptik wrote:

As a side note I had to come up with a home baked way of storing country and state names as abbreviations and displaying them as full names.  Is there a better way to do this? If not I'll be happy to post my abbr.xml and abbr.rb somewhere because it might be ugly and hacky but it works

I have done this in the past by creating a countries and states tables and referencing those. Both ways have their advantages.

However, requiring files directly in the Thing class is a little weird. Files are normally required in environment.rb.

Railscasts - Free Ruby on Rails Screencasts

Re: ActiveRecord::ConfigurationError: Association [...] was not found

ryanb wrote:

I have done this in the past by creating a countries and states tables and referencing those. Both ways have their advantages.

However, requiring files directly in the Thing class is a little weird. Files are normally required in environment.rb.

ahh... thanks I'll do it there... I'd figured out that the application.rb allowed me to include it once for all views, but that didnt translate to the model (hey I disclaimed that I was a newby)... I hadnt gotten far enough to bother with finding that out yet since this is the only model which needs it.  I will, however, move all references to it into the environment.rb now, and mark that off of my list of "little details."  Now to figure out how to used memcached to store the parsed abbr.xml data so that it's not being constantly regenerated smile

Cheers, and thanks for your help!