Ajax in RoR - observe_field

Hey, I'm trying to achieve something relatively simple and missing something that is probably very simple, which I'm loosing my head over. My situation is the following: I have two tables: -education_plans -students Each student has_one ed_plan and each ed_plan belongs to one student. What I'm trying to achieve is on the form when new ed_plan is created, I want to have a text box where I can enter st_id(not primary key of the students table, my own id created for each student). Then the call is made to the get_student_info method where student info is pulled and associated with the education plan. This is where the problem is because I render text or template from get_student_info method fine, but how do I at the same time associate returned info about the student with ed_plan. I've tried number of various combinations and I just can't get it to work. I'm really hoping you guys can help me out. So my new view on ed_plans looks like this: <% form_for(@education_plan) do |f| %>   <%= f.error_messages %> <table>   <tr>     <td>Student name</td>     <td>Student ID</td>     <td>Grade</td>   </tr>   <tr>     <td><div id="student_info"></div></td>

      <td><%=text_field_tag :st_id %></td>

    <%= observe_field(:st_id, :frequency => 0.25, :update => :student_id,                       :url =>{:action => :get_student_info}, :with => 'st_id') %>     <td><div id="student_grade"></div></td>   </tr>   <tr>     <td><%= f.label :comments %></td>     <td><%= f.text_area(:comments, :cols => 30, :rows => 4) %></td>   </tr>   <tr>     <td><%= f.label :service_code %></td>     <td><%= f.text_field(:service_code, :size =>3) %></td>   </tr>   <tr>     <td><%= f.label :school_number %></td>     <td><%= f.text_field(:school_number, :size =>3) %></td>   </tr>

</table>     <%= f.submit 'Create'%>

the get_student_info methods looks like this:   def get_student_info        @student = Student.find_by_osis(params[:osis]) # @education_plan.student_id = @student        return @student   end

Also, one thing I couldn't get that if I uncomment the line # @education_plan.student_id = @student I get error method not available for nil object, which is very weird because that method is in the EducationPlan controller. THanks for you help...

The error message says that you're calling a method on a nil object. If you uncomment that line, you will be calling the student_id method on @education_plan instance, but @education_plan is nil there.

Leonardo Mateo wrote:

Leonardo Mateo wrote:

made to the get_student_info method where student info is pulled and �<tr> � �<%= observe_field(:st_id, :frequency => 0.25, :update => � �<td><%= f.label :service_code %></td>

EducationPlan controller.

The error message says that you're calling a method on a nil object. If you uncomment that line, you will be calling the student_id method on @education_plan instance, but @education_plan is nil there.

-- Leonardo Mateo. There's no place like ~

Thanks. Why is it nil if the method is part of the controller?

Which method is part of the controller? you are referencing an instance variable (@education_plan) which is not defined yet. The method in question, here, is student_id which is from the model (EducationPlan) but the object where you're trying to call this method from is not of a EducationPlan instance, it is not even an instance, it is nil, and that's why you get that error.

And also how can I create an association between education_plan and student based on the ajax call from education_plan?

I really don't understand how you want to do the association here. The AJAX call behaves exactly as any other calls in the terms of the controller. If a Student has one EducationPlan, and you have: @student = Student.find(whatever) you should be able to do: @student.education_plan and @student.education_plan=

So, if you're retrieving the student from the database, you'll get the associated education plan.

It looks like you have a misconception of the ActiveRecord associations, have you read the guide[1] for this? maybe it can help you to get it right.

[1]Active Record Associations — Ruby on Rails Guides

Hope it helps.-

Yes, this looks like another concept error on instance variables from Misiek

OK, now the situation is clearer for me. There's something you're not getting from associations, let's see if with the example you get it more clear. If you want to create the association when you create the education plan, why would you try to get it on the get_info action and not on the create action? When you get (render) the student info on the create form for education plan, you should keep the student id and send it with the rest of the education plan parameters as the education_plan[student_id]. Then, in the create action, you can do EducationPlan.new(params[:education_plan]) (or whatever your params are called) and, if you have the right student_id the relationship should be created automatically.

If it doesn't work, you should "pastie" your code so we can debug it better.

Hope it helps.

Leonardo Mateo wrote:

Leonardo Mateo wrote:

saved when the form is submitted?

OK, now the situation is clearer for me. There's something you're not getting from associations, let's see if with the example you get it more clear. If you want to create the association when you create the education plan, why would you try to get it on the get_info action and not on the create action? When you get (render) the student info on the create form for education plan, you should keep the student id and send it with the rest of the education plan parameters as the education_plan[student_id]. Then, in the create action, you can do EducationPlan.new(params[:education_plan]) (or whatever your params are called) and, if you have the right student_id the relationship should be created automatically.

If it doesn't work, you should "pastie" your code so we can debug it better.

Hope it helps.

-- Leonardo Mateo. There's no place like ~

was on the road past two days..... I want to do exactly what you are saying Leonardo. Here is my code for education_plans_controller.rb ---------------------------- def create @education_plan = EducationPlan.new(params[:education_plan]) # this is my sneaky way around, which I don't want to use....You'll see what i'm doing when you see the view

I think that with this is enough.

# @student = Student.find(params[:student_id]) # @tutor = Tutor.find(params[:tutor_id]) # @education_plan.student = @student # @education_plan.tutor = @tutor

You have you tutor_id and student_id parameters but you're using them in the wrong way. You should send the parameters inside the params[:education_plan] array. You should receive, in the controller, params[:education_plan][:student_id] and params[:education_plan][:tutor_id] instead of params[:student_id] and params[:tutor_id]. So you need to modify your view to accomplish this. Once you have this, in your controller: @education_plans = EducationPlan.new(params[:education_plan]) will do all the magic with relationships. You don't need to do @education_plan.student = Student.find(student_id)

One more thing, if you're testing, you can ensure that behavior in a test and then adjust you application. If you're not testing... well.. you should.

Hope it helps.

I created clean new app to test and poke around. I got to work, but I wonder if there is still a better way to handle it and someone could point it our. So i have two models: class Project < ActiveRecord::Base   has_one :task end

class Widget < ActiveRecord::Base     belongs_to :project     validates_presence_of :project     validates_associated :project end widget/new view <h1>New widget</h1> <% form_for(@widget) do |f| %>   <%= f.error_messages %>   <%= text_field_tag :wids %>   <p>     <%= f.label :name %><br />     <%= f.text_field :name %>   </p>   <p>     <%= f.label :wid %><br />     <%= f.text_field :wid %>   </p>   <p>   <div id='disp'></div>   <%= observe_field 'wids' ,:url => { :action => :find_project },       :frequency => 0.25,       :update => :disp,       :with => 'wids'       %>     <%= f.submit 'Create' %>   </p> <% end %> <%= link_to 'Back', widgets_path %>

widget controller def find_project   @project = Project.find(params[:wids])   render :partial => 'find_project' end _find_project view <p>   <b>Name:</b>   <%=h @project.name %> </p> <%= hidden_field_tag 'widget[project_id]',@project.id %>

The piece that doesn't sit well with me is the immediate line above as its not dynamic. Meaning if I wanted to reuse find_project method in ajax call from other controller than widgets then I havd hard code hidden_field_tag name for that controller as well.

Is there a better way to handle this situation?