0

Im getting this error on rendering the form for New controller method:

undefined method `teacher_id' for # Extracted source (around line #8):

 <table summary="Student form fields">
  <tr>
    <th>Teacher ID</th>
    <td><%= f.number_field :teacher_id %></td>  # this is line 8
  </tr>
  <tr>
    <th>Parent ID</th>

This is new.html.erb:

<h1>Add A Student</h1>

<%= form_for @student, :url => { :action => 'create'}, :html => { :multipart => true } do |f| %>
<table summary="Student form fields">
   <tr>
     <th>Teacher ID</th>
     <td><%= f.number_field :teacher_id %></td>
   </tr>
   <tr>
     <th>Parent ID</th>
     <td><%= f.number_field :parent_id %></td>
   </tr>
   <tr>
     <th>FirstName</th>
     <td><%= f.text_field :firstname %></td>
   </tr>
   <tr>
     <th>LastName</th>
     <td><%= f.text_field :lastname %></td>
   </tr>
   <tr>
     <th>Date of Birth</th>
     <td><%= f.date_field :dob %></td>
   </tr>
   <tr>
     <th>Email</th>
     <td><%= f.email_field :email %></td>
   </tr>
   <tr>
     <th>Cellphone</th>
     <td><%= f.telephone_field :cellphone %></td>
   </tr>
   <tr>
     <th>Username</th>
     <td><%= f.text_field :username %></td>
   </tr>
   <tr>
   <tr>
     <th>Password</th>
     <td><%= f.password_field :password %></td>
   </tr>
   <tr>
     <th>Confirm Password</th>
     <td><%= f.password_field :password_confirmation %></td>
   </tr>
   <tr>
     <th>Address Street#</th>
     <td><%= f.text_field :addr_streetno %></td>
     <th>Apt #</th>
     <td><%= f.number_field :addr_aptno %></td>
   </tr>
   <tr>
     <th>City</th>
     <td><%= f.text_field :addr_city %></td>
     <th>State</th>
     <td><%= f.text_field :addr_state %></td>
     <th>Zip</th>
     <td><%= f.number_field :addr_zip %></td>
   </tr>
   <tr>
     <th>Photo</th>
     <td><%= f.file_field :photo %></td>
   </tr>
</table>

   <%= f.submit 'Create Student' %>
<% end %>

<% if @student.errors.any? %>
    <ul class="Signup_Errors">
    <% for message_error in @student.errors.full_messages %>
      <li>* <%= message_error %></li>
    <% end %>
    </ul>
  <% end %>
</div>

'This is the student.rb model file:

class Student < ActiveRecord::Base
    #attr_accessor :teacherid, :firstname, :lastname, :dob, :isadult, 
    #              :email, :cellphone, :username, :password, :addr_streetno, 
    #             :addr_city, :addr_state, :addr_zip, :photo

    #has_secure_password

    belongs_to :parent
    belongs_to :teacher

    attr_accessor :email, :password, :password_confirmation

    EMAIL_REGEX = /\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z/i
    validates :username, :presence => true, :uniqueness => true, :length => { :in => 3..20 }
    validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
    validates_confirmation_of :password

    scope :sorted, lambda { order("students.firstname ASC")}
end

This is the structure of the student table:

create_table :students do |t|
   t.references :parents
   t.references :teachers, null: false

   t.string :firstname, null: false
   t.string :lastname, null: false
   t.date :dob, null: false
   t.boolean :isadult, null: false, default: false
   t.string :email, null: false
   t.string :cellphone
   t.string :username, null: false
   t.string :password_digest, null: false
   t.string :addr_streetno
   t.integer :addr_aptno
   t.string :addr_city
   t.string :addr_state
   t.integer :addr_zip
   t.binary :photo, :limit => 0.5.megabyte

   t.timestamps
 end 
gvermag
  • 389
  • 1
  • 5
  • 12
  • Im unable to understand why RoR thinks that @student.teacher_id is a method. Is this a problem with the syntax that I am using with form_for construct. Earlier, I had the form_tag construct and just adapted it with minimal change for form_for construct. – gvermag May 18 '14 at 04:07
  • Please let me know what is the issue in the code or whether I need to change my approach. @Wali Ali – gvermag May 18 '14 at 04:07

2 Answers2

0

Your table definition says teachers where it should be teacher, since it’s a belongs_to. It should read this way:

t.references :parent
t.references :teacher, null: false
Buck Doyle
  • 6,333
  • 1
  • 22
  • 35
  • so it doesnt matter if the name of the FK table was actually parents or teachers? I thought it was referring to the name of the FK tables. But is the singular and plural decided by whether its a belongs_to at the student table. In the teacher model, I have a has_many: students – gvermag May 18 '14 at 04:21
  • The Rails/ActiveRecord convention is that the parent model `has_many :children` but the child only `belongs_to :parent`. – Buck Doyle May 18 '14 at 04:23
  • Thanks. I meant to ask that the student table migration file should have t.references :parent even if the the parent table is actually plural (parents) in its own migration file? – gvermag May 18 '14 at 04:35
  • Yes, the convention is that table names are pluralised. But a student only references their `parent` and `teacher`, since in your setup, they only have one. – Buck Doyle May 18 '14 at 04:38
  • the fix worked in rendering the form. This was a key learning for me. Thanks for your response. – gvermag May 18 '14 at 13:18
0

Buck Doyle's answer is right, however, to expand on it, I would mention that when you receive a no method error - it means your object does not have the attributes you're calling

--

Attributes

You have to remember everything in Ruby is an object, which Rails populates with a series of attributes. Although we call them attributes in Rails, the fact is every object (created with a Rails Model / Ruby Class) has a series of methods which are called each time you have an instance of it

Therefore, if you have a model, what you're really doing is defining the attributes / methods which Rails is able to call. That's why you can use virtual attributes with attr_accessor - this tells the model (a Ruby class) to include those methods

Simply, your ActiveRecord objects will always be populated with attributes from your database, as well as any virtual attributes you set. The no method error means you're trying to call attributes which don't exist

--

Fix

The way to fix a no method error is to ensure you have the correct columns in your db

As highlighted by Buck Doyle, the most likely issue you have is you've referenced t.references :teachers, null: false in your migration, which it should be singular

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • 1
    Rich, thanks for yours and Buck Doyle's responses. It was indeed the case. I had to redo the db migrations after fixing the t.references :parent & t.references :teacher in the student table migration file. Now the http://localhost:3000/student/new url shows up the form. Whether or not, it will save the data that it gets in the form is another matter. I will open another issue for such issues. – gvermag May 18 '14 at 13:17