Terror Doctors

No one should be surprised that several of the (latest) British terrorists are highly educated Muslims. Two years ago, a respected special ed teacher was one of the 7-7 bombers.

While we disagree with Osama bin Laden’s goal of “civilizational apartheid,” it nonetheless may be wise to minimize the globe’s commerce with the Arab world while pushing as much humiliating feedback to her as possible.

Modern Islam is Radical Islam,” indeed. This is the fault of a deeply sick Arab world that we must do our best to transform into something human.

Extending the Question and QuestionList Interfaces

Not going to change the experimental code yet — that’s too big for this day of vacation, whatever I said previously.

Today we’ll improve the student interface to allow questions to be ordered, question lists to be ordered, and a new “question” type (instruction) to be added.

My props to Geek Skillz and Programming Ruby‘s “class Hash” for coming in useful today.


First, go into app/models/question_type-rb and add a new QuestionType item

QuestionType.add_item :INSTRUCTION, 6

Then create a new module, TextfieldType (app/modles/textfield_type.rb) with the following code:

class TextfieldType
def self.add_item(key,value)
@hash ||= {}
@hash[key]=value
end

def self.const_missing(key)
@hash[key]
end

def self.each
@hash.each {|key,value| yield(key,value)}
end

def self.find_selection_list
@hash
end

TextfieldType.add_item :TEXT, 1
TextfieldType.add_item :HTML, 2
end

Then create two migrations, because we will add ordering to both Questions and QuestionLists

ruby script/generate migration alter_questions_add_ordering
ruby script/generate migration alter_questionlists_add_ordering

022_alter_questions_add_ordering.rb reads:

class AlterQuestionsAddOrdering < ActiveRecord::Migration
def self.up
add_column :questions, :ordering, :integer
end

def self.down
remove_column :question_lists, :ordering
end
end

while 023_alter_questionlists_add_ordering.rb is:

class AlterQuestionlistsAddOrdering < ActiveRecord::Migration
def self.up
add_column :question_lists, :ordering, :integer
end

def self.down
remove_column :question_lists, :ordering
end
end

Then rake db:migrate.

Update app/views/manage_questions/list.rhtml:

<h1>Listing questions</h1>

<% form_tag :action => ‘update_ordering’ do %>

<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Order</th>
<th>Display</th>
<th>Type</th>
<th>Question List</th>
</tr>
<% for question in @questions %>
<tr>
<td><%= question.id %></td>
<td><%= question.name %></td>
<td><%= text_field :question_ordering, question.id, :value => question.ordering, :size=>3 %></td>
<td><%= question.display_text %></td>
<td><%= question.type_id %></td>
<td><%= QuestionList.find_name_by_id(question.list_id) %></td>
<td><%= link_to ‘Show’, :action => ‘show’, :id => question %></td>
<td><%= link_to ‘Edit’, :action => ‘edit’, :id => question %></td>
<td><%= link_to ‘Destroy’, { :action => ‘destroy’, :id => question }, :confirm => ‘Are you sure?’, :method => :post %></td>
</tr>
<% end %>
</table>

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

<br /><%= submit_tag ‘Update Ordering’ %>
<br /><%= link_to ‘New question’, :action => ‘new’ %>
<% end %>

In manage_questions_controller.rb, create the new function update_ordering

def update_ordering
@questions_to_order = params[:question_ordering]
@questions_to_order.each { |question_id, new_ordering_value|
if new_ordering_value
@question = Question.find(question_id)
@question.ordering = new_ordering_value
@question.save
end
}
flash[:notice] = "Ordering updated as appropriate"
redirect_to :action => ‘list’
end

And update def list as so:

def list
@question_pages, @questions = paginate :questions, :per_page => 10, :order => ‘Ordering ASC, ID ASC’
end

After a short break, I realize a problem: putting Ordering in the Questions table makes sense, because each Question is in only one QuestionList table. However, each QuestionList can be in multiple conditions, so Ordering has to go out of QuestionList and into QuestionListConditions; So create a new migration

ruby script/generate migration move_order_from_questionlist_to_questionlistcondition

that file looks like:

class MoveOrderFromQuestionlistToQuestionconditionlist < ActiveRecord::Migration
def self.up
remove_column :question_lists, :ordering
add_column :question_list_conditions, :ordering, :integer
end

def self.down
add_column :question_lists, :ordering, :integer
remove_column :question_list_conditions, :ordering
end
end

Then rake db:migrate.

Now back to the main job

create a new function for the QuestionListCondition model:

def self.find_by_condition_id(condition_id)
to_find = find(:all,:conditions=> {:condition_id => condition_id }, :order => "Ordering, question_list_id")
end

UPdate app/views/manage_question_lists/list.rhtml:

<h1>Listing question_lists</h1>

<% form_tag :action => ‘update_ordering’ do %>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Order</th>
<th>Description</th>
</tr>

<% for question_list in @question_lists %>
<tr>
<td><%= h question_list.id %></td>
<td><%= h question_list.name %></td>
<td>(varies)</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>
</tr>
<% end %>

<% for experiment in @experiments %>
<% @conditions = Condition.find_conditions_array(experiment.id) %>
<% for condition in @conditions %>
<tr><td colspan="7">  </td></tr>
<tr><td colspan="7"><b><%= experiment.name %> – <%= condition.name %></b></td></tr>
<% @question_list_conditions = QuestionListCondition.find_by_condition_id(condition.id) %>
<% for question_list_condition in @question_list_conditions %>
<% question_list = QuestionList.find(question_list_condition.question_list_id) %>
<tr>
<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>
</tr>
<% end %>
<% end %>
<% end %>
</table>
<%= link_to ‘Previous page’, { :page => @question_list_pages.current.previous } if @question_list_pages.current.previous %>
<%= link_to ‘Next page’, { :page => @question_list_pages.current.next } if @question_list_pages.current.next %>

<br /><%= submit_tag ‘Update Ordering’ %>
<% end %>
<br />s<%= link_to ‘New question_list’, :action => ‘new’ %>

Update app/controllers/manage_question_lists_controller.rb, in the function list

def list
@question_list_pages, @question_lists = paginate :question_lists, :per_page => 10
@experiments = Experiment.find(:all)
end

and create a new function, update ordering (remember we wrote a very similar function for the questions controller):

def update_ordering
@questions_to_order = params[:question_ordering]
@questions_to_order.each { |question_list_condition_id, new_ordering_value|
if new_ordering_value
@question = QuestionListCondition.find(question_list_condition_id)
@question.ordering = new_ordering_value
@question.save
end
}
flash[:notice] = "Ordering updated as appropriate"
redirect_to :action => ‘list’
end

The next day of work will, hopefully, upgrade the experiment interface