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]http://guides.rubyonrails.org/association_basics.html

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?