rails 3.0.3 - ActiveRecord::Relation, undefined method error

brg picture brg · Dec 27, 2010 · Viewed 16.8k times · Source

I am having this unexplained ActiveRecord::Relation, undefined method error . I don't know why, since my model association are well defined and the event table has the foreign keys for the user table. I tried using this fix but it failed: Rails 3 ActiveRecord::Relation random associations behavior

event.rb

class Event < ActiveRecord::Base
  belongs_to :user

  attr_accessible :event_name, :Starts_at, :finish, :tracks
end

user.rb

class User < ActiveRecord::Base
  has_many :events, :dependent => :destroy

  attr_accessible :name, :event_attributes

  accepts_nested_attributes_for :events,  :allow_destroy => true

end

schema.rb

ActiveRecord::Schema.define(:version => 20101201180355) do

  create_table "events", :force => true do |t|

    t.string   "event_name"
    t.string   "tracks"
    t.datetime "starts_at"
    t.datetime "finish"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
  end
end

error message

NoMethodError in Users#index 
undefined method `events' for #<ActiveRecord::Relation:0x4177518>

Extracted source (around line #10):

7:  <th><%= sortable "Tracks" %></th>

8:   </tr>


10:  <% @users.events.each do |event| %> 

11: <% debugger %> 

12:   <tr>

13:     <td><%= event.starts_at %></td>

Trace of template inclusion: app/views/users/index.html.erb

Rails.root: C:/rails_project1/events_manager
Application Trace | Framework Trace | Full Trace

app/views/users/_event_user.html.erb:10:in `_app_views_users__event_user_html_erb__412443848_34308540_1390678'
app/views/users/index.html.erb:7:in `_app_views_users_index_html_erb___603337143_34316016_0'

Answer

cimtico picture cimtico · Jan 3, 2011

If you read the error message closely, it doesn't say the problem is the relation with the events. It says:

undefined method `events' for

10: <% @users.events.each do |event| %>

I also had trouble understanding this when i first bumped into it

This means that the finder of @users is returning a Relation object instead of the user list (or the not well named object) you expected.

If you are using a find anywhere, you should change it for a "where(:id => ...).first"

For example, you probably have something that looks like this in your controller:

@users = User.find(<conditions go here>)

This should be changed to:

@users = User.where(<conditions go here>).all

Or you could use the resulting relation object after the "where" for extra conditions and sql "configuration"

@users = User.where(:admin => true).where('created_at > ?', min_date).order('created_at').limit(10).all

A relation object will execute the query only when a ".first" ".all" ".each" or ".inspect" is invoked on it.