Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undefined method for ActiveRecord::Relation

Tags:

User model

class User < ActiveRecord::Base   has_many :medicalhistory  end 

Mdedicalhistory model

class Medicalhistory < ActiveRecord::Base   belongs_to :user #foreign key -> user_id   accepts_nested_attributes_for :user end 

Error

undefined method `lastname' for #<ActiveRecord::Relation:0xb6ad89d0>   #this works @medicalhistory = Medicalhistory.find(current_user.id)  print   "\n" + @medicalhistory.lastname  #this doesn't! @medicalhistory = Medicalhistory.where("user_id = ?", current_user.id) print   "\n" + @medicalhistory.lastname #error on this line 
like image 448
Omnipresent Avatar asked May 14 '11 21:05

Omnipresent


People also ask

What is ActiveRecord relation?

Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet). Once you run that query by calling to_a , each , first etc. on that Relation a single instance or an array of ActiveRecord::Base instances will be returned.

What are ActiveRecord methods?

The active record pattern is an approach to accessing data in a database. A database table or view is wrapped into a class. Thus, an object instance is tied to a single row in the table. After creation of an object, a new row is added to the table upon save.

Is ActiveRecord relation an array?

The key thing to note is that #find returns the actual record while #where returns an ActiveRecord::Relation which basically acts like an array.

What does ActiveRecord base do?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending. Edit: as Mike points out, in this case ActiveRecord is a module...


2 Answers

Well, you are getting back an object of ActiveRecord::Relation, not your model instance, thus the error since there is no method called lastname in ActiveRecord::Relation.

Doing @medicalhistory.first.lastname works because @medicalhistory.first is returning the first instance of the model that was found by the where.

Also, you can print out @medicalhistory.class for both the working and "erroring" code and see how they are different.

like image 50
Zabba Avatar answered Sep 25 '22 21:09

Zabba


One other thing to note, :medicalhistory should be plural as it is a has_many relationship

So your code:

class User < ActiveRecord::Base   has_many :medicalhistory  end 

Should be written:

class User < ActiveRecord::Base   has_many :medicalhistories  end 

From the Rails docs (found here)

The name of the other model is pluralized when declaring a has_many association.

This is because rails automatically infers the class name from the association name.

If a user only had_one medicalhistory this would be singular as you had written:

class User < ActiveRecord::Base   has_one :medicalhistory  end 

I know you already accepted an answer, but thought this would help reduce further errors/confusion.

like image 32
Thomas Avatar answered Sep 26 '22 21:09

Thomas