Error Catching, and Implementing Notes

Today we repair what we broke last time.

This entry is the most boring of all, as all it does is fix errors and “features” that were introduced (intentionally or no) in the prior work. At the end, the student experiment integrates quesiton lists and notes, but doesn’t actually save the results.


Try to go to the manage_question_lists controller and, at least with how I’ve entered data, you get this unfriendly message

ActiveRecord::RecordNotFound in Manage_question_lists#index

Showing app/views/manage_question_lists/list.rhtml where line #32 raised:

Couldn’t find QuestionList without an ID

Extracted source (around line #32)

..

32: <% question_list = QuestionList.find(question_list_condition.question_list_id) %>

First, it’s easy to see that this is a bad design. It makes catching errors hard, as we see right now. So in question_list.rb, add a new function

def self.find_by_id(id)
begin
found_object = find(id)
@to_return = found_object
rescue
logger.error("Error: No record found for id " + id.to_s + " generated by question_list.rb:find_by_id")
end
@to_return
end

The error reveals that there is a QuestionListID (no. 4, in my case) being called, in spite of its presense in QuestionListConditions. Now we’ll do some begin/rescue/end code in _list.rhtml to make it error out prettier (wouldn’t want this error while showing it off someday!) while next finding out what causes this problem in the first place.

The code to do the first part is pretty simple. Also We’ll check to make sure that the question_list exists — so now we have a double-layer of code!

<% if question_list %>
<tr>
<% begin %>
<td><%= h question_list.id %></td>
<td><%= h question_list.name %></td>
<td><%= text_field :question_ordering, question_list_condition.id, :value => question_list_condition.ordering, :size=>3 %></td>
<td><%= h question_list.description %></td>
<td><%= link_to ‘Show’, :action => ‘show’, :id => question_list %></td>
<td><%= link_to ‘Edit’, :action => ‘edit’, :id => question_list %></td>
<td><%= link_to ‘Destroy’, { :action => ‘destroy’, :id => question_list }, :confirm => ‘Are you sure?’, :method => :post %></td>
<% rescue %>
<br />Error encountered</td>
<% end %>
</tr>
<% else %>
<tr /><td>QL <%= condition.id %> does not exist </td></tr>
<% end %>

(That extra td is there after Error encountered because the problem presumable happened while in a table cell)

Presumably this problem is caused by a question_list that existed but was deleted. And indeed, the question_list id tag appears in two places: in question_lists and question_list_conditions. Therefore, whenever a question_list is destroyed, the question_list_conditions with that question_list_id should be destroyed as well.

in models,question_list_condition.rb, add the following function

def self.destroy_by_question_list_id(question_list_id)
question_list_conditions = find(:all,$conditions=>{:question_list_id => question_list_id})
for question_list_condition in question_list_conditions
QuestionListCondition(question_list_condition.id).destroy
end
end

And update controllers/manage_question_lists_controller.rb to have

def destroy
begin
question_list_id = params[:id]
QuestionList.find(question_list_id).destroy
QuestionListConditions.find(:all, :conditions=>{:question_list_id =>question_list_id}).destroy
QuestionListCondition.destroy_by_question_list_id(question_list_id)
flash[:notice] = ‘QuestionList was successfully deleted.’
rescue
flash[:notice] = ‘QuestionList was not successfully deleted.’
end
redirect_to :action => ‘list’
end

Next to fix: manage_question_options for a similar problem. Update views/manage_question_options/list.rhtml to read as follows:

<h1>Listing question_options</h1>

<table>
<tr>
<th>ID</th>
<th>Question ID</th>
<th>Question Text</th>
<th>Option</th>
<th>Display Text</th>
</tr>
<% for question_option in @question_options %>
<% begin %>
<tr>
<td><%= question_option.id %></td>
<td><%= question_option.question_id %></td>
<td><%= Question.find_name_by_id(question_option.question_id) %></td>
<td><%= question_option.option_id %></td>
<td><%= question_option.display_text %></td>
<% rescue %>
<br />QuestionOption no. <%= question_option.id %> generated an error</td>
<% end %>
<td><%= link_to ‘Show’, :action => ‘show’, :id => question_option %></td>
<td><%= link_to ‘Edit’, :action => ‘edit’, :id => question_option %></td>
<td><%= link_to ‘Destroy’, { :action => ‘destroy’, :id => question_option }, :confirm => ‘Are you sure?’, :method => :post %></td>
</tr>
<% end %>
</table>

<%= link_to ‘Previous page’, { :page => @question_option_pages.current.previous } if @question_option_pages.current.previous %>
<%= link_to ‘Next page’, { :page => @question_option_pages.current.next } if @question_option_pages.current.next %>

<br />

<%= link_to ‘New question_option’, :action => ‘new’ %>

Now that this works, I went through and deleted all the questions and question_lists stuff. Now to re-create. First, after a question_list is created, send the user to the create new question screen with this line:

redirect_to :controller => ‘manage_questions’, :action => ‘new’

in manage_question_lists_controll.rb:create()

Now that’s done, I went through and created some appropiate question_lists and questions. Finally, we need to finish up the student controller to allow experiments to be taken.

Add the following code to the _question_types.rhtml partial under the students view

<% if question.type_id == QuestionType::NOTES_MATRIX or question.type_id == QuestionType::NOTES_LINEAR %>

<% @notes_fields = NotesField.find_by_condition(@student.condition_id) %>
<% @notes_records = NotesRecord.find_by_condition(@student.condition_id) %>
<%= render :partial => "notes_view" %>
<% end %>

The concluding portion of the students_controller.rb:run_experiment function should read

else
flash[:notice] = ‘Finished experiment.’
redirect_to :action => ‘index’

end
end

And now we can talk through the notes experiment!

Of course, it doesn’t save, but that’s a project for another time…

Leave a Reply

Your email address will not be published. Required fields are marked *