Mock Student Interface

This morning’s accomplishments were buzzwordy. Using ruby on rails’ Ajax features I built a student interface to the web database that I set up yesterday. There were a couple hour-long periods of frustrating because I am still new to the language, but in the end I’m happy with what was done.


Ruby on Rails + Ajax

HTML special characters needed for putting this online are courtesy of HTML Special Character Converter


Having got the administration system running, now for student-side code.

First, create a “students” controller with a method “index” (94)

ruby script/generate controller students index

then in controllers/student_controller.rb, define the index method as such (95)

def index
@experiments = Experiment.find_experiments
end

and then within the model/experiments.rb, define the find_experiments function (96)

def self.find_experiments
find(:all, :order => “name” ).map {|u| [u.name, u.id]
end

and finally in views/students/index.rhtml (remember from yesterday)

<h1>Select your experiment</h1>
select :login, :experiment_id, @experiments

Create the code necessary for students sections (106)

rake db:sessions:create

and fron the same page, uncomment the following line from config/environment.rb:

config.action_controller.session_store = :active_record_store

this will have rubyonrails rely on the database, not the file session, to keep track of sessions. Now just rake db:migrate and restart the script/server to store the sessions!

The section on AJAX starts on page 128 of Agile Web Development with Rails — 2nd Edition, though I also used onlamp. So go back to the view/students/index.rhtml file and chang e it to be so (128-129):

<html>
<head>
<title>Notes on Rails Mock Student Interface</title>
<%= javascript_include_tag "prototype" %>
</head>
<body>
<h3>Add to list using Ajax</h3>
<%= form_remote_tag(:update => "login_with_condition",
:url => { :action => :select_condition_from_experiment },
:position => "top" ) %>
New item text:
<%= select :selected_experiment, :experiment_id, @experiments %>
<%= submit_tag "Select Experiment" %>
<%= end_form_tag %>
<div id="login_with_condition"></div>
</body>
</html>

while updating the controller:

def select_condition_from_experiment
selected_experiment_id = params[:selected_experiment][:experiment_id]
render_text "<li>" + selected_experiment_id + "</li>"
end

Now that this works, the next step is to dynamically generate a form that will allow us to select the condition. (Note that this isn’t a step-by-step tutorial — I’m noting mistakes that I made. This page is a thinking out loud excersize.)

Go to condition.rb and add a method self.find_conditions (this code adapted from rubyonrailsblog):

def self.find_conditions(selected_experiment_id)
@conditions = Condition.find(:all, :conditions => [‘experiment_id = ?’ , selected_experiment_id ] ).map {|u| [u.name, u.id] }
end

update select_condition_from_experiment like so:

def select_condition_from_experiment
@experiments = Experiment.find_experiments
selected_experiment_id = params[:selected_experiment][:experiment_id]
@conditions = Condition.find_conditions(selected_experiment_id)
render :partial => “select_condition”
end

And create a partial view titled app/views/students/_select_condition.rhtml that reads:

<%= form_remote_tag(:update => "notetaking_display",
:url => { :action => :select_notes_from_condition },
:position => "top" ) %>
New item text:
<%= select :selected_condition, :condition_id, @conditions %>
<%= submit_tag "Select Condition" %>
<%= end_form_tag %>
<div id="notetaking_display"></div>

Next up, create a select_notes_from_conditio module in the student controller

In app/models/notes_field.rb, add the following function

def self.find_by_condition(selected_condition_id)
@entries = find(:all, :conditions => [‘condition_id = ?’ , selected_condition_id ] )
end

But the exact same function in notes_record.rb, and add the following to students_controller.rb

def select_notes_from_condition
selected_condition_id = params[:selected_condition][:condition_id]

@notes_fields = NotesField.find_by_condition(selected_condition_id)
@notes_records = NotesRecord.find_by_condition(selected_condition_id)

render :partial => “notes_view”
end

Then in _notes_view.rhtml:

<h1>Note-Taking Matrix</h1>
<table border="1">
<tr>
<td>  </td>
<% for notes_record in @notes_records %>
<td><%= h(notes_record.name) %></td>
<% end %>
</tr>
<% for notes_field in @notes_fields %>
<tr>
<td><%= notes_field.name %></td>
</tr>
<% end %>
</table>

Done for the day! Next up will be login in specific students and storing their notes.